/// <summary> /// Creates a valid authentication token used to create the access_token. /// </summary> private static AuthenticationTicket CreateAuthenticationTicket(LoginResult result, GrantResourceOwnerCredentialsContext context) { var identity = new ClaimsIdentity(context.Options.AuthenticationScheme); identity.AddClaim(ClaimTypes.Name, result.UserName, OpenIdConnectConstants.Destinations.AccessToken, OpenIdConnectConstants.Destinations.IdentityToken); identity.AddClaim(ClaimTypes.NameIdentifier, result.UserId.ToString(), OpenIdConnectConstants.Destinations.AccessToken, OpenIdConnectConstants.Destinations.IdentityToken); var properties = new AuthenticationProperties(); var principal = new ClaimsPrincipal(new[] { identity }); return(CreateAuthenticationTicket(principal, properties, context.Options, context)); }
public async Task <IActionResult> ExternalLogin(string provider, string returnUrl) { returnUrl = Url.Action("ExternalLoginCallback", new { returnUrl = returnUrl }); // windows authentication is modeled as external in the asp.net core authentication manager, so we need special handling if (AccountOptions.WindowsAuthenticationSchemes.Contains(provider)) { // but they don't support the redirect uri, so this URL is re-triggered when we call challenge if (HttpContext.User is WindowsPrincipal wp) { var props = new Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties(); props.Items.Add("scheme", AccountOptions.WindowsAuthenticationProviderName); var id = new ClaimsIdentity(provider); id.AddClaim(new Claim(JwtClaimTypes.Subject, HttpContext.User.Identity.Name)); id.AddClaim(new Claim(JwtClaimTypes.Name, HttpContext.User.Identity.Name)); // add the groups as claims -- be careful if the number of groups is too large if (AccountOptions.IncludeWindowsGroups) { var wi = wp.Identity as WindowsIdentity; var groups = wi.Groups.Translate(typeof(NTAccount)); var roles = groups.Select(x => new Claim(JwtClaimTypes.Role, x.Value)); id.AddClaims(roles); } await HttpContext.SignInAsync(id.GetSubjectId(), new ClaimsPrincipal(id)); if (string.IsNullOrWhiteSpace(returnUrl)) { returnUrl = "/ManageHome"; } return(Redirect(returnUrl)); } else { // this triggers all of the windows auth schemes we're supporting so the browser can use what it supports return(new ChallengeResult(AccountOptions.WindowsAuthenticationSchemes)); } } else { // start challenge and roundtrip the return URL var props = new Microsoft.AspNetCore.Authentication.AuthenticationProperties { RedirectUri = returnUrl, Items = { { "scheme", provider } } }; return(new ChallengeResult(provider, props)); } }
public async Task <IActionResult> Login(LoginInputModel model) { if (ModelState.IsValid) { // validate username/password against in-memory store if (_users.ValidateCredentials(model.Username, model.Password)) { AuthenticationProperties props = null; // only set explicit expiration here if persistent. // otherwise we reply upon expiration configured in cookie middleware. if (AccountOptions.AllowRememberLogin && model.RememberLogin) { props = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration) }; } ; // issue authentication cookie with subject ID and username var user = _users.FindByUsername(model.Username); await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username)); await HttpContext.Authentication.SignInAsync(user.SubjectId, user.Username, props); // make sure the returnUrl is still valid, and if yes - redirect back to authorize endpoint or a local page if (_interaction.IsValidReturnUrl(model.ReturnUrl) || Url.IsLocalUrl(model.ReturnUrl)) { return(Redirect(model.ReturnUrl)); } return(Redirect("~/")); } await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials")); ModelState.AddModelError("", AccountOptions.InvalidCredentialsErrorMessage); } // something went wrong, show form with error var vm = await _account.BuildLoginViewModelAsync(model); return(View(vm)); }
public async Task <IActionResult> Login(LoginViewModel model) { if (ModelState.IsValid) { var user = await _loginService.FindByUsername(model.Email); if (await _loginService.ValidateCredentials(user, model.Password)) { Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties props = null; if (model.RememberMe) { props = new Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.AddYears(10) }; } ; await _loginService.SignIn(user); // make sure the returnUrl is still valid, and if yes - redirect back to authorize endpoint if (_interaction.IsValidReturnUrl(model.ReturnUrl)) { return(Redirect(model.ReturnUrl)); } return(Redirect("~/")); } ModelState.AddModelError("", "Invalid username or password."); } // something went wrong, show form with error var vm = await BuildLoginViewModelAsync(model); ViewData["ReturnUrl"] = model.ReturnUrl; return(View(vm)); }
public async Task <IActionResult> ExternalLogin(string provider, string returnUrl) { returnUrl = Url.Action("ExternalLoginCallback", new { returnUrl = returnUrl }); // windows authentication is modeled as external in the asp.net core authentication manager, so we need special handling if (AccountOptions.WindowsAuthenticationSchemes.Contains(provider)) { // but they don't support the redirect uri, so this URL is re-triggered when we call challenge if (HttpContext.User is WindowsPrincipal) { var props = new Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties(); props.Items.Add("scheme", AccountOptions.WindowsAuthenticationProviderName); var id = new ClaimsIdentity(provider); id.AddClaim(new Claim(ClaimTypes.NameIdentifier, HttpContext.User.Identity.Name)); id.AddClaim(new Claim(ClaimTypes.Name, HttpContext.User.Identity.Name)); await HttpContext.Authentication.SignInAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme, new ClaimsPrincipal(id), props); return(Redirect(returnUrl)); } else { // this triggers all of the windows auth schemes we're supporting so the browser can use what it supports return(new ChallengeResult(AccountOptions.WindowsAuthenticationSchemes)); } } else { // start challenge and roundtrip the return URL var props = new Microsoft.AspNetCore.Authentication.AuthenticationProperties { RedirectUri = returnUrl, Items = { { "scheme", provider } } }; return(new ChallengeResult(provider, props)); } }
private static AuthenticationTicket CreateAuthenticationTicket(ClaimsPrincipal principal, AuthenticationProperties authenticationProperties, OpenIdConnectServerOptions options, BaseContext context) { var configuration = Configuration(context); var ticket = new AuthenticationTicket(principal, authenticationProperties, options.AuthenticationScheme); ticket.SetResources(configuration.ApiHostName()); ticket.SetScopes(OpenIdConnectConstants.Scopes.OpenId, OpenIdConnectConstants.Scopes.Email, OpenIdConnectConstants.Scopes.Profile, OpenIdConnectConstants.Scopes.OfflineAccess); return(ticket); }
public async Task <IActionResult> ExternalLoginCallback(string returnUrl) { // read external identity from the temporary cookie var info = await HttpContext.Authentication.GetAuthenticateInfoAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); var tempUser = info?.Principal; if (tempUser == null) { throw new Exception("External authentication error"); } // retrieve claims of the external user var claims = tempUser.Claims.ToList(); // try to determine the unique id of the external user - the most common claim type for that are the sub claim and the NameIdentifier // depending on the external provider, some other claim type might be used var userIdClaim = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject); if (userIdClaim == null) { userIdClaim = claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier); } if (userIdClaim == null) { throw new Exception("Unknown userid"); } // remove the user id claim from the claims collection and move to the userId property // also set the name of the external authentication provider claims.Remove(userIdClaim); var provider = info.Properties.Items["scheme"]; var userId = userIdClaim.Value; // check if the external user is already provisioned var user = _users.FindByExternalProvider(provider, userId); if (user == null) { // this sample simply auto-provisions new external user // another common approach is to start a registrations workflow first user = _users.AutoProvisionUser(provider, userId, claims); } var additionalClaims = new List <Claim>(); // if the external system sent a session id claim, copy it over var sid = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId); if (sid != null) { additionalClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value)); } // if the external provider issued an id_token, we'll keep it for signout httpmicro.AuthenticationProperties props = null; var id_token = info.Properties.GetTokenValue("id_token"); if (id_token != null) { props = new httpmicro.AuthenticationProperties(); props.StoreTokens(new[] { new AuthenticationToken { Name = "id_token", Value = id_token } }); } // issue authentication cookie for user await _events.RaiseAsync(new UserLoginSuccessEvent(provider, userId, user.SubjectId, user.Username)); await HttpContext.Authentication.SignInAsync(user.SubjectId, user.Username, provider, props, additionalClaims.ToArray()); // delete temporary cookie used during external authentication await HttpContext.Authentication.SignOutAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); // validate return URL and redirect back to authorization endpoint or a local page if (_interaction.IsValidReturnUrl(returnUrl) || Url.IsLocalUrl(returnUrl)) { return(Redirect(returnUrl)); } return(Redirect("~/")); }