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
Related
I'm using WebForms with forms authentication. I'm connecting my application with an rest api token mechanism.
My problem is that I want to ask for my new access token using my refreshtoken.
I currently do this job in Global.asax Application_AuthenticateRequest method.
When I obtain the accesstoken i update the ticket but i am redirected to the login page.
I've try to use Response.Redirect and i am redirected to the original url but i lost the state of the page. It's as if I has reloaded the page. Somebody know what i'm doing wrong?
Below is my global.asax code in VB.net:
Thanks!
Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As EventArgs)
Try
If Request.Cookies(FormsAuthentication.FormsCookieName) IsNot Nothing Then
Dim authCookie As HttpCookie = (Request.Cookies(FormsAuthentication.FormsCookieName))
If Not String.IsNullOrEmpty(authCookie.Value) Then
Dim ticket = FormsAuthentication.Decrypt(authCookie.Value)
If ticket.Expired Then
'reauth cookie Is My refreshtoken
If Request.Cookies("reAuthCookie") IsNot Nothing Then
Dim funciones As New Funciones.Usuarios
Dim reAuthCookie As HttpCookie = Request.Cookies("reAuthCookie")
If Not String.IsNullOrEmpty(reAuthCookie.Value) Then
Dim refreshToken As String = reAuthCookie.Value(0).ToString
Dim login As Entidades.Login = funciones.renovarAccessToken(refreshToken)
Dim ticketExpiration As Date
ticketExpiration = Date.Now.AddSeconds(CDbl(login.Expires_in) - 20)
Dim userData As String = Newtonsoft.Json.JsonConvert.SerializeObject(login)
ticket = New FormsAuthenticationTicket(1, login.Username, DateTime.Now,
ticketExpiration, True,
userData, FormsAuthentication.FormsCookiePath)
Dim encTicket As String = FormsAuthentication.Encrypt(ticket)
HttpContext.Current.Response.Cookies.Add(New HttpCookie(FormsAuthentication.FormsCookieName, encTicket))
Response.Cookies.Remove("reAuthCookie")
reAuthCookie.Expires = Now.AddMonths(2)
reAuthCookie.Path = "/"
reAuthCookie.Value = login.Refresh_token
Response.Cookies.Add(reAuthCookie)
End If
End If
End If
End If
Else
If Request.Cookies("reAuthCookie") IsNot Nothing Then
Dim funciones As New Funciones.Usuarios
Dim reAuthCookie As HttpCookie = Request.Cookies("reAuthCookie")
If Not String.IsNullOrEmpty(reAuthCookie.Value) Then
Dim refreshToken As String = reAuthCookie.Value.ToString
Dim login As Entidades.Login = funciones.renovarAccessToken(refreshToken)
Dim ticketExpiration As Date
ticketExpiration = Date.Now.AddSeconds(CDbl(login.Expires_in) - 20)
Dim userData As String = Newtonsoft.Json.JsonConvert.SerializeObject(login)
Dim ticket = New FormsAuthenticationTicket(1, login.Username, DateTime.Now,
ticketExpiration, True,
userData, FormsAuthentication.FormsCookiePath)
Dim encTicket As String = FormsAuthentication.Encrypt(ticket)
Response.Cookies.Add(New HttpCookie(FormsAuthentication.FormsCookieName, encTicket))
Response.Cookies.Remove("reAuthCookie")
reAuthCookie.Expires = Now.AddMonths(2)
reAuthCookie.Path = "/"
reAuthCookie.Value = login.Refresh_token
Response.Cookies.Add(reAuthCookie)
End If
End If
End If
Catch ex As Exception
Throw ex
End Try
End Sub
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
I know this is ugly and I know I should have it in try blocks I've just been tinkering trying to get it to work. I'm missing something here and I would really appreciate some help figuring it out. All I'm trying to do is to create a page with a text box for the login name as well as one for the old password and two for the new password. To add more information the error I'm getting now is
Unknown name. (Exception from HRESULT: 0x80020006 (DISP_E_UNKNOWNNAME))
when i try to invoke the ChangePassword
Dim userid As String
Dim password As String
Dim login As String
Dim check As String
login = txtLogin.Text
userid = txtLogin.Text
password = txtOldPass.Text
Dim entry As DirectoryEntry = New DirectoryEntry("LDAP://OU=PaidUsers,DC=LOCAL,DC=bb", "LOCAL\" & userid, password)
Dim obj As Object = entry.NativeObject
Dim search As DirectorySearcher = New DirectorySearcher(entry)
search.SearchScope = SearchScope.Subtree
search.Filter = "(SAMAccountName=" & login & ")"
Dim result As SearchResult = search.FindOne()
check = CType(result.Properties("sAMAccountName")(0), String)
If check = login Then
If txtNewPass.Text = txtNewPass2.Text Then
entry = result.GetDirectoryEntry()
entry.Username = "LOCAL\" & check
entry.Password = txtOldPass.Text
entry.AuthenticationType = AuthenticationTypes.Secure
entry.Options.Referral = ReferralChasingOption.All
entry.Invoke("ChangePassword", txtOldPass.Text, txtNewPass.Text)
entry.CommitChanges()
lblSuccess.Visible = True
Else
lblPasswdError.Visible = True
End If
Else
lblError.Visible = True
End If
The error that fixed it was the command to Get the directory entry before Invoking the "ChangePassword". What I didn't realize is once I go into the IF logic the entry directory entry didn't have the account I was trying to change, hence the UnknownName error. Calling the result of my initial query of LDAP found the user account and it worked like a charm. The working code is below;
lblError.Visible = False
lblSuccess.Visible = False
lblPasswdError.Visible = False
lblCatch.Visible = False
Dim userid As String
Dim password As String
Dim check As String
userid = txtLogin.Text
password = txtOldPass.Text
Dim entry As DirectoryEntry = New DirectoryEntry("LDAP://OU=PaidUsers,DC=LOCAL,DC=bb", "LOCAL\" & userid, password)
Try
Dim search As DirectorySearcher = New DirectorySearcher(entry)
search.SearchScope = SearchScope.Subtree
search.Filter = "(SAMAccountName=" & userid & ")"
Dim result As SearchResult = search.FindOne()
check = CType(result.Properties("sAMAccountName")(0), String)
If check <> Nothing Then
If check = userid Then
If txtNewPass.Text = txtNewPass2.Text Then
entry = result.GetDirectoryEntry()
entry.Username = "LOCAL\" & check
entry.Password = txtOldPass.Text
entry.AuthenticationType = AuthenticationTypes.Secure
entry.Options.Referral = ReferralChasingOption.All
entry.Invoke("ChangePassword", txtOldPass.Text, txtNewPass.Text)
entry.CommitChanges()
lblSuccess.Visible = True
Else
lblPasswdError.Visible = True
End If
Else
lblError.Visible = True
End If
Else
lblError.Visible = True
End If
Catch ex As Exception
lblCatch.Text = "Error message: " + ex.InnerException.Message
lblCatch.Visible = True
End Try
All --
I am able to retieve the FullName value
I am trying to retrieve an email address from Active Directory but using the following code in my ASP.Net Web Forms project that is using Windows Authentication:
Dim wi As System.Security.Principal.WindowsIdentity = System.Security.Principal.WindowsIdentity.GetCurrent()
Dim a As String() = wi.Name.Split(New Char() {"\"c}) '' Context.User.Identity.Name.Split('\')
Dim ADEntry As System.DirectoryServices.DirectoryEntry = New System.DirectoryServices.DirectoryEntry(Convert.ToString("WinNT://" + a(0) + "/" + a(1)))
Dim Name As String = ADEntry.Properties("FullName").Value.ToString()
Dim Email As String = ADEntry.Properties("mail").Value.ToString()
when I get to the line of code where I'm try to retrieve the email address I get an "Object reference not set to an instance of an object." error. I have tried using EmailAddress, E-Mail. I think the problem is that I am simply using the wrong keyword. I am able to retrieve the FullName value.
Thanks to Davide Piras who send me this link, I found a suitable solution:
Dim wi As System.Security.Principal.WindowsIdentity = System.Security.Principal.WindowsIdentity.GetCurrent()
Dim a As String() = wi.Name.Split(New Char() {"\"c}) '' Context.User.Identity.Name.Split('\')
Dim dc As PrincipalContext = New PrincipalContext(ContextType.Domain, "DomainName")
Dim adUser As UserPrincipal = UserPrincipal.FindByIdentity(dc, a(1))
Dim Email As String = adUser.EmailAddress
This code works for me..
Reference to System.DirectoryServices.AccountManagement
static string GetADUserEmailAddress(string username)
{
using (var pctx = new PrincipalContext(ContextType.Domain))
{
using (UserPrincipal up = UserPrincipal.FindByIdentity(pctx, username))
{
return up != null && !String.IsNullOrEmpty(up.EmailAddress) ? up.EmailAddress : string.Empty;
}
}
}
to use it:
lblEmail.Text = GetADUserEmailAddress(Request.ServerVariables["AUTH_USER"]);
I got the following error
{"The specified domain either does not exist or could not be
contacted. "}
at the line
Dim adResults = adSearch.FindOne.Path
Can anyone suggest why it is ? Seeing the below code
Dim ID As FormsIdentity = DirectCast(User.Identity, FormsIdentity)
Dim ticket As FormsAuthenticationTicket = ID.Ticket
Dim adTicketID As String = ticket.Name
Dim adSearch As New DirectorySearcher
adSearch.Filter = ("(userPrincipalName=" & adTicketID & ")")
Dim adResults = adSearch.FindOne.Path
Dim adResultsDirectory As New DirectoryEntry(adResults)
Dim found As Boolean = False
For Each entry In adResultsDirectory.Properties("memberOf")
Response.Write(entry)
Response.Write("<br/>")
If entry = "CN=GroupName,CN=UserGroup,DC=my,DC=domain,DC=com" Then
found = True
End If
Next
If Not (found) Then
Response.Redirect("login.aspx")
End If
Where is your domain specified?
First parameter for DirectoryEntry should be your AD server, something like this: LDAP://adserver.
Here is the code that I am using for checking whether user is authenticated in AD:
Dim dsDirectoryEntry As New DirectoryEntry("LDAP://" & domain, userName, password)
Dim dsSearch As New DirectorySearcher(dsDirectoryEntry)
Dim dsResults As SearchResult = dsSearch.FindOne()
If dsResults IsNot Nothing Then
Return True
Else
Return False
End If
Domain I am reading from configuration, userName and password are from login form input.