I've been trying to work this problem out for over a week and can't seem to work out why it isn't working. I'm using ASP.NET Web Forms.
I have updated the following on my IdentityConfig.vb file to reduce the password requirement so it doesn't need any uppercase or numeric value:
manager.PasswordValidator = New PasswordValidator() With {
.RequiredLength = 4,
.RequireNonLetterOrDigit = False,
.RequireDigit = False,
.RequireLowercase = False,
.RequireUppercase = False
}
And this is the code I have to create a user
Protected Sub CreateUser_Click(sender As Object, e As EventArgs)
Dim userName As String = TextBox1.Text
Dim manager = Context.GetOwinContext().GetUserManager(Of ApplicationUserManager)()
Dim signInManager = Context.GetOwinContext().Get(Of ApplicationSignInManager)()
Dim user = New ApplicationUser() With {.UserName = userName, .Email = userName}
Dim result = manager.Create(user, TextBox2.Text)
If result.Succeeded Then
signInManager.SignIn(user, isPersistent:=False, rememberBrowser:=False)
Response.Redirect("/member")
Else
Literal1.Text = result.Errors.FirstOrDefault()
End If
End Sub
But for some reason no matter what I try it's using the default password requirement and giving me the following validation messages when trying to create an account.
Passwords must be at least 6 characters. Passwords must have at least one non letter or digit character. Passwords must have at least one lowercase ('a'-'z'). Passwords must have at least one uppercase ('A'-'Z').
I have moved the register page out of the /account section.
Does anybody know what I've done wrong?
Edit 1: Reference to ApplicationUserManager in my IdentityConfig file
Public Class ApplicationUserManager
Inherits UserManager(Of ApplicationUser)
Public Sub New(store As IUserStore(Of ApplicationUser))
MyBase.New(store)
End Sub
Public Shared Function Create(options As IdentityFactoryOptions(Of ApplicationUserManager), context As IOwinContext) As ApplicationUserManager
Dim manager = New ApplicationUserManager(New UserStore(Of ApplicationUser)(context.[Get](Of ApplicationDbContext)()))
' Configure validation logic for usernames
manager.UserValidator = New UserValidator(Of ApplicationUser)(manager) With {
.AllowOnlyAlphanumericUserNames = False,
.RequireUniqueEmail = True
}
' Configure validation logic for passwords
manager.PasswordValidator = New PasswordValidator() With {
.RequiredLength = 4,
.RequireNonLetterOrDigit = False,
.RequireDigit = False,
.RequireLowercase = False,
.RequireUppercase = False
}
' Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user. '
' You can write your own provider and plug in here. '
manager.RegisterTwoFactorProvider("Phone Code", New PhoneNumberTokenProvider(Of ApplicationUser)() With {
.MessageFormat = "Your security code is {0}"
})
manager.RegisterTwoFactorProvider("Email Code", New EmailTokenProvider(Of ApplicationUser)() With {
.Subject = "Security Code",
.BodyFormat = "Your security code is {0}"
})
' Configure user lockout defaults '
manager.UserLockoutEnabledByDefault = True
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5)
manager.MaxFailedAccessAttemptsBeforeLockout = 5
manager.EmailService = New EmailService()
manager.SmsService = New SmsService()
Dim dataProtectionProvider = options.DataProtectionProvider
If dataProtectionProvider IsNot Nothing Then
manager.UserTokenProvider = New DataProtectorTokenProvider(Of ApplicationUser)(dataProtectionProvider.Create("ASP.NET Identity"))
End If
Return manager
End Function
End Class
Related
I don't want use email as username, I amended the code to add first name and last name but cant get it to use usernames, it keeps going to email in aspnetusers table
I'd like the users to navigate to other users using their username and keeping emails confidential
Protected Sub Unnamed4_Click(sender As Object, e As EventArgs)
If Me.Password.Text = Me.ConfirmPassword.Text Then
Dim userName As String = signinSrEmail.Text
Dim manager = Context.GetOwinContext().GetUserManager(Of ApplicationUserManager)()
Dim signInManager = Context.GetOwinContext().Get(Of ApplicationSignInManager)()
Dim user = New ApplicationUser() With {.UserName = userName, .Email = userName, .FirstName = TextBoxFname.Text, .Surname = TextBoxSName.Text}
Dim result = manager.Create(user, Password.Text.ToString)
If result.Succeeded Then
'For more information on how To enable account confirmation And password reset please visit https://go.microsoft.com/fwlink/?LinkID=320771
Dim code = manager.GenerateEmailConfirmationToken(user.Id)
Dim callbackUrl = IdentityHelper.GetUserConfirmationRedirectUrl(code, user.Id, Request)
manager.SendEmail(user.Id, "Confirm your account", "Please confirm your account by clicking here.")
If user.EmailConfirmed Then
'Response.Cookies("UserName").Expires = DateTime.Now.AddDays(30)
FormsAuthentication.SetAuthCookie(user.Id, False)
signInManager.SignIn(user, isPersistent:=False, rememberBrowser:=True)
IdentityHelper.RedirectToReturnUrl(Request.QueryString("ReturnUrl"), Response)
Else
ErrorMessage.Text = "An email has been sent to your account. Please view the email and confirm your account to complete the registration process."
End If
Else
errormessage.Text = result.Errors.FirstOrDefault()
End If
Else
errormessage.Text = "Passwords do not match"
End If
End Sub
End Class
You are storing Email Id in userName. if you don't want to use email as user name then you have to use this
Dim userName As String = TextBoxFname.Text +" "+.Surname = TextBoxSName.Text
when a user authenticates with Identity Server 3, AuthorizationCodeReceived never fires. RedirectToIdentityProvider does get fired but thats it. I am trying to call a function that will get the users email or windows ID, and then add a custom claim. But without the AuthorizationCodeReceived method being called, I am not sure how to do that. Anyone have experience with this? Not sure if it matters, but my code is ASP.net windows form (not MVC)
Here is my code:
Public Sub ConfigureAuth(app As IAppBuilder)
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap = New Dictionary(Of String, String)
app.UseCookieAuthentication(New CookieAuthenticationOptions() With {
.AuthenticationType = CookieAuthenticationDefaults.AuthenticationType
})
Dim OpenIdAuthOption = New OpenIdConnectAuthenticationOptions() With {
.Authority = "https://myidentityserver.azurewebsites.net/core/",
.ClientId = "adfafasfasdfa",
.RedirectUri = "https://localhost:44321/default.aspx/",
.ResponseType = ("access_token"),
.RequireHttpsMetadata = False,
.SignInAsAuthenticationType = "Cookies",
.Notifications = New OpenIdConnectAuthenticationNotifications() With {
.AuthorizationCodeReceived = Function(ctx)
Dim claimPrincipal As ClaimsPrincipal = ctx.AuthenticationTicket.Identity.Claims
TransformClaims(claimPrincipal)
Return Task.FromResult(0)
End Function,
.RedirectToIdentityProvider = Function(context)
RedirectLogin(context)
Return Task.FromResult(0)
End Function
}
}
app.UseOpenIdConnectAuthentication(OpenIdAuthOption)
End Sub
I am trying to set up some password policies, I managed to successfully do this in C#, but I need to convert the code into VB. There are two issues that I cannot figure out:
1) app.UseUserManagerFactory does not exist;
It states UseUserManagerFactory is not a member of Owin.IAppBuilder
2) The OnCreate attribute when instantiating the Provider is not being passed correctly
Public Sub ConfigureAuth(app As IAppBuilder)
'Configure the UserManager
app.UseUserManagerFactory(New IdentityFactoryOptions(Of ApplicationUserManager)() With { _
.DataProtectionProvider = app.GetDataProtectionProvider(), _
.Provider = New IdentityFactoryProvider(Of ApplicationUserManager)() With { _
.OnCreate = ApplicationUserManager.Create _
} _
})
Here is the Create function for the sake of completeness:
Public Shared Function Create(options As IdentityFactoryOptions(Of ApplicationUserManager))
Dim manager = New ApplicationUserManager(New ApplicationUserStore(New ApplicationDbContext()))
manager.UserValidator = New UserValidator(Of ApplicationUser)(manager) With {.AllowOnlyAlphanumericUserNames = False, .RequireUniqueEmail = True}
manager.PasswordValidator = New PasswordValidator()
Dim dataProtectionProvider = options.DataProtectionProvider
If (dataProtectionProvider IsNot Nothing) Then
' Do stuff
End If
Return manager
End Function
Any help would be appreciated, my VB skills coupled with the lack of documentation has me scratching my head.
Is there a way in Visual Basic to check if the user's password is set to never expire in Active Directory?
I've found a way to find the last date it was changed, but I can't find the other available options.
Dim de As DirectoryServices.DirectoryEntry = GetUser(uDetails.username)
Dim objUser = GetObject(de.Path)
If objUser.PasswordLastChanged < DateTime.Now.AddMonths(-3) Then
...
Where can I find a list of all available objUser properties?
If you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
Basically, you can define a domain context and easily find users and/or groups in AD:
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
if(user != null)
{
// one of the properties exposed is "PasswordNeverExpires" (bool)
if(user.PasswordNeverExpires)
{
// do something here....
...
}
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!
For .NET 2.0 you can use some LDAP. The magic part is userAccountControl:1.2.840.113556.1.4.803:=65536. The first part is the property that you want to search, the second means "bitwise AND" and the third is the bitwise flag to check, in this case the 17th bit. You can see more on the bitwise AND and OR in Active Directory in How to query Active Directory by using a bitwise filter.
In the code below update the SearchRoot variable with your domain controller (DC) and FQDN.
Imports System.DirectoryServices
Public Class Form1
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
''//Bind to the root of our domain
''// YOU_DOMAIN_CONTROLLER should be one of your DCs
''// EXAMPLE and COM are the parts of your FQDN
Dim SearchRoot As DirectoryEntry = New DirectoryEntry("LDAP://YOUR_DOMAIN_CONTROLLER/dc=EXAMPLE,dc=COM")
''//Create a searcher bound to the root
Dim Searcher As DirectorySearcher = New DirectorySearcher(SearchRoot)
''//Set our filer. The last part is dumb but that is the way that LDAP was built.
''//It basically does a bitwise AND looking for the 17th bit to be set on that property "userAccountControl" which is the "password never expires" bit
''//See this if you care to learn more http://support.microsoft.com/kb/269181
Searcher.Filter = "(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=65536))"
''//Find all of the results
Dim Results = Searcher.FindAll()
Dim DE As DirectoryEntry
''//Loop through each result
For Each R As SearchResult In Results
''//Get the result as a DirectoryEntry object
DE = R.GetDirectoryEntry()
''//Output the object name
Console.WriteLine(DE.Name)
Next
End Sub
End Class
public bool isPasswordExpired(String p_UserName, String p_DomainName)
{
bool m_Check=false;
int m_Val1 = (int)de1.Properties["userAccountControl"].Value;
int m_Val2 = (int) 0x10000;
if (Convert.ToBoolean(m_Val1 & m_Val2))
{
m_Check = true;
} //end
return m_Check
}
You could use the following code originally from here that I've translated from C# and modified a little bit according to your question (added a getter):
Dim pwdNeverExpires = getPasswordNeverExpires("Tim")
setPasswordNeverExpires("Tim", True)
' See http://msdn.microsoft.com/en-us/library/aa772300(VS.85).aspx
<Flags()> _
Private Enum ADS_USER_FLAG_ENUM
ADS_UF_SCRIPT = 1
' 0x1
ADS_UF_ACCOUNTDISABLE = 2
' 0x2
ADS_UF_HOMEDIR_REQUIRED = 8
' 0x8
ADS_UF_LOCKOUT = 16
' 0x10
ADS_UF_PASSWD_NOTREQD = 32
' 0x20
ADS_UF_PASSWD_CANT_CHANGE = 64
' 0x40
ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 128
' 0x80
ADS_UF_TEMP_DUPLICATE_ACCOUNT = 256
' 0x100
ADS_UF_NORMAL_ACCOUNT = 512
' 0x200
ADS_UF_INTERDOMAIN_TRUST_ACCOUNT = 2048
' 0x800
ADS_UF_WORKSTATION_TRUST_ACCOUNT = 4096
' 0x1000
ADS_UF_SERVER_TRUST_ACCOUNT = 8192
' 0x2000
ADS_UF_DONT_EXPIRE_PASSWD = 65536
' 0x10000
ADS_UF_MNS_LOGON_ACCOUNT = 131072
' 0x20000
ADS_UF_SMARTCARD_REQUIRED = 262144
' 0x40000
ADS_UF_TRUSTED_FOR_DELEGATION = 524288
' 0x80000
ADS_UF_NOT_DELEGATED = 1048576
' 0x100000
ADS_UF_USE_DES_KEY_ONLY = 2097152
' 0x200000
ADS_UF_DONT_REQUIRE_PREAUTH = 4194304
' 0x400000
ADS_UF_PASSWORD_EXPIRED = 8388608
' 0x800000
ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 16777216
' 0x1000000
End Enum
Protected Overridable Function getPasswordNeverExpires(ByVal userName As String) As Boolean
Const userNameString As String = "userName"
Const userFlagsString As String = "userFlags"
Dim machineName As String = Environment.MachineName
Dim userInThisComputerDirectoryEntry As DirectoryEntry = getUserInThisComputerDirectoryEntry(machineName, userName)
If userInThisComputerDirectoryEntry Is Nothing Then
Throw New ArgumentException("not found in " & machineName, userNameString)
End If
Dim userFlagsProperties As PropertyValueCollection = userInThisComputerDirectoryEntry.Properties(userFlagsString)
Dim userFlags As ADS_USER_FLAG_ENUM = CType(userFlagsProperties.Value, ADS_USER_FLAG_ENUM)
Return userFlags = (userFlags Or ADS_USER_FLAG_ENUM.ADS_UF_DONT_EXPIRE_PASSWD)
End Function
Protected Overridable Sub setPasswordNeverExpires(ByVal userName As String, ByVal passwordNeverExpires As Boolean)
Const userNameString As String = "userName"
Const userFlagsString As String = "userFlags"
Dim machineName As String = Environment.MachineName
Dim userInThisComputerDirectoryEntry As DirectoryEntry = getUserInThisComputerDirectoryEntry(machineName, userName)
If userInThisComputerDirectoryEntry Is Nothing Then
Throw New ArgumentException("not found in " & machineName, userNameString)
End If
Dim userFlagsProperties As PropertyValueCollection = userInThisComputerDirectoryEntry.Properties(userFlagsString)
Dim userFlags As ADS_USER_FLAG_ENUM = CType(userFlagsProperties.Value, ADS_USER_FLAG_ENUM)
Dim newUserFlags As ADS_USER_FLAG_ENUM = userFlags
If passwordNeverExpires Then
newUserFlags = newUserFlags Or ADS_USER_FLAG_ENUM.ADS_UF_DONT_EXPIRE_PASSWD
Else
newUserFlags = newUserFlags And (Not ADS_USER_FLAG_ENUM.ADS_UF_DONT_EXPIRE_PASSWD)
End If
userFlagsProperties.Value = newUserFlags
userInThisComputerDirectoryEntry.CommitChanges()
End Sub
Protected Overridable Function getUserInThisComputerDirectoryEntry(ByVal machineName As String, ByVal userName As String) As DirectoryEntry
Dim computerDirectoryEntry As DirectoryEntry = getComputerDirectoryEntry(machineName)
Const userSchemaClassName As String = "user"
Return computerDirectoryEntry.Children.Find(userName, userSchemaClassName)
End Function
Protected Overridable Function getComputerDirectoryEntry(ByVal machineName As String) As DirectoryEntry
'Initiate DirectoryEntry Class To Connect Through WINNT Protocol
' see: http://msdn.microsoft.com/en-us/library/system.directoryservices.directoryentry.path.aspx
Const pathUsingWinNTComputerMask As String = "WinNT://{0},computer"
Dim path As String = String.Format(pathUsingWinNTComputerMask, machineName)
Dim thisComputerDirectoryEntry As New DirectoryEntry(path)
Return thisComputerDirectoryEntry
End Function
You have to add a reference to System.DirectoryServices. I have tested it on Windows Server 2008 with .NET Framework 4 (it should also work under 2.0) without Active Directory. But check it out yourself and feel free to extend it to get/set other properties as well or connect to other machines (SomeDomain/OtherComputerName instead of Environment.MachineName).
Can someone help me pls. I am ready to deploy my web application. I have a contact form that i want users to send me a message. Ive created the smtp when i click on submit, i get the error message cannot be sent.
The application is still on my local machine maybe thats why. But i just want to know if this code is good for my form:
Imports System.Net.Mail
Partial Class contact
Inherits System.Web.UI.Page
Protected Sub CustomValidator1_ServerValidate(ByVal source As Object, ByVal args As System.Web.UI.WebControls.ServerValidateEventArgs) Handles CustomValidator1.ServerValidate
If txtComments.Text.Length > 300 Then
args.IsValid = False
Else
args.IsValid = True
End If
End Sub
Protected Sub Wizard1_FinishButtonClick(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.WizardNavigationEventArgs) Handles Wizard1.FinishButtonClick
SendMail(txtEmail.Text, txtComments.Text)
End Sub
Private Sub SendMail(ByVal from As String, ByVal body As String)
Dim mailServerName As String = "SMTP.relay-hosting.secureserver.net"
Dim message As MailMessage = New MailMessage(from, "collins#collinsegbe.com", "feedback", body)
Dim mailClient As SmtpClient = New SmtpClient
mailClient.Host = mailServerName
mailClient.Send(message)
message.Dispose()
End Sub
End Class
The error is indicated on this line of code: mailClient.Send(message)
I will appreciate help from anyone
protected void Button9_Click(object sender, EventArgs e)
{
{
var fromAddress = new MailAddress("rusty109.stud#gmail.com");
var toAddress = new MailAddress(TextBox13.Text);
const string fromPassword = "commando1";
string subject = TextBox14.Text;
string body = TextBox12.Text;
var smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(fromAddress.Address, fromPassword),
Timeout = 20000
};
using (var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body
})
{
smtp.Send(message);
}
}
}
my old code when i wanted to email, you can use the gmail account if you wish, nothing in it... was set up to use this code :)
using System.Net.Mail;
using System.Net;
You need to add the username and password for the SMTP server by setting the SmtpClient's Credential property to an instance of the NetworkCredential class.