public static AuthenticationTransaction PrepareAuthentication(this HttpContext context, string callbackUrl, string returnUrl) { var middlewareOptions = context.RequestServices.GetRequiredService<IOptions<OpenIdConnectOptions>>().Value; var nonce = middlewareOptions.ProtocolValidator.GenerateNonce(); // Add the nonce. context.Response.Cookies.Append( OpenIdConnectDefaults.CookieNoncePrefix + middlewareOptions.StringDataFormat.Protect(nonce), NonceProperty, new CookieOptions { HttpOnly = true, Secure = context.Request.IsHttps, Expires = DateTimeOffset.UtcNow + middlewareOptions.ProtocolValidator.NonceLifetime }); // Prepare state. var authenticationProperties = new AuthenticationProperties() { RedirectUri = returnUrl }; AddCallbackUrl(callbackUrl, authenticationProperties); GenerateCorrelationId(context, middlewareOptions, authenticationProperties); // Generate state. var state = Uri.EscapeDataString(middlewareOptions.StateDataFormat.Protect(authenticationProperties)); // Return nonce to the Lock. return new AuthenticationTransaction(nonce, state); }
public async Task ExecuteResultAsync_InvokesSignInAsyncOnConfiguredScheme() { // Arrange var principal = new ClaimsPrincipal(); var authProperties = new AuthenticationProperties(); var authenticationManager = new Mock<AuthenticationManager>(); authenticationManager .Setup(c => c.SignInAsync("Scheme1", principal, authProperties)) .Returns(TaskCache.CompletedTask) .Verifiable(); var httpContext = new Mock<HttpContext>(); httpContext.Setup(c => c.RequestServices).Returns(CreateServices()); httpContext.Setup(c => c.Authentication).Returns(authenticationManager.Object); var result = new SignInResult("Scheme1", principal, authProperties); var routeData = new RouteData(); var actionContext = new ActionContext( httpContext.Object, routeData, new ActionDescriptor()); // Act await result.ExecuteResultAsync(actionContext); // Assert authenticationManager.Verify(); }
/// <summary> /// Main constructor to create <see cref="BasicAuthInfo"/> /// </summary> /// <param name="credential">Basic auth credential from the request</param> /// <param name="properties">Basic auth properties from the request</param> /// <param name="httpContext">Context from the request</param> /// <param name="authenticationScheme">Authentication scheme from the configuration</param> internal BasicAuthInfo(BasicAuthCredential credential, AuthenticationProperties properties, HttpContext httpContext, string authenticationScheme) { this.Credential = credential; this.Properties = properties; this.HttpContext = httpContext; this.AuthenticationScheme = authenticationScheme; }
/// <summary> /// Creates a new context object. /// </summary> /// <param name="context">The HTTP request context.</param> /// <param name="options">The Twitter middleware options.</param> /// <param name="properties">The authentication properties of the challenge.</param> /// <param name="redirectUri">The initial redirect URI.</param> public TwitterRedirectToAuthorizationEndpointContext(HttpContext context, TwitterOptions options, AuthenticationProperties properties, string redirectUri) : base(context, options) { RedirectUri = redirectUri; Properties = properties; }
/// <summary> /// Creates a new context object. /// </summary> /// <param name="context">The HTTP request context.</param> /// <param name="options">The <see cref="OAuthOptions"/>.</param> /// <param name="properties">The authentication properties of the challenge.</param> /// <param name="redirectUri">The initial redirect URI.</param> public OAuthRedirectToAuthorizationContext(HttpContext context, OAuthOptions options, AuthenticationProperties properties, string redirectUri) : base(context) { RedirectUri = redirectUri; Properties = properties; Options = options; }
private AuthPropertiesTokenCache(AuthenticationProperties authProperties) : base() { _authProperties = authProperties; BeforeAccess = BeforeAccessNotificationWithProperties; AfterAccess = AfterAccessNotificationWithProperties; BeforeWrite = BeforeWriteNotification; }
public IActionResult Google() { var props = new AuthenticationProperties { RedirectUri = "/home/about" }; return new ChallengeResult("Google", props); }
public ActionResult Google() { var props = new AuthenticationProperties { RedirectUri = "/account/register" }; return new ChallengeResult("Google", props); }
// Leave it up to authentication handler to do the right thing for the challenge public virtual Task ChallengeAsync(string authenticationScheme, AuthenticationProperties properties) { if (string.IsNullOrEmpty(authenticationScheme)) { throw new ArgumentException(nameof(authenticationScheme)); } return ChallengeAsync(authenticationScheme, properties, ChallengeBehavior.Automatic); }
/// <summary> /// Initializes a new instance of the <see cref="AuthenticationTicket"/> class /// </summary> /// <param name="principal">the <see cref="ClaimsPrincipal"/> that represents the authenticated user.</param> /// <param name="properties">additional properties that can be consumed by the user or runtime.</param> /// <param name="authenticationScheme">the authentication middleware that was responsible for this ticket.</param> public AuthenticationTicket(ClaimsPrincipal principal, AuthenticationProperties properties, string authenticationScheme) { if (principal == null) { throw new ArgumentNullException(nameof(principal)); } AuthenticationScheme = authenticationScheme; Principal = principal; Properties = properties ?? new AuthenticationProperties(); }
/// <summary> /// /// </summary> /// <param name="context"></param> /// <param name="options"></param> /// <param name="properties"></param> /// <param name="cookieOptions"></param> public CookieSigningOutContext( HttpContext context, CookieAuthenticationOptions options, AuthenticationProperties properties, CookieOptions cookieOptions) : base(context, options) { CookieOptions = cookieOptions; Properties = properties; }
public ActionResult SocialLogin([FromForm]string scheme, string returnUrl = null) { var props = new AuthenticationProperties { RedirectUri = Url.Action("sociallogincallback", "Account", new {ReturnUrl = returnUrl}) }; props.Items["orgId"] = HttpContext.GetTenant<Organization>().Id.ToString(); return new ChallengeResult(scheme, props); }
/// <summary> /// Initializes a new instance of the <see cref="AuthenticationResponseGrant"/> class. /// </summary> /// <param name="principal"></param> /// <param name="properties"></param> public AuthenticationResponseGrant(ClaimsPrincipal principal, AuthenticationProperties properties) { if (principal == null) { throw new ArgumentNullException("principal"); } Principal = principal; Identity = principal.Identities.FirstOrDefault(); Properties = properties; }
/// <summary> /// Creates a new instance of the context object. /// </summary> /// <param name="context">The HTTP request context</param> /// <param name="options">The middleware options</param> /// <param name="authenticationScheme">Initializes AuthenticationScheme property</param> /// <param name="principal">Initializes Principal property</param> /// <param name="properties">Initializes Properties property</param> public CookieSignedInContext( HttpContext context, CookieAuthenticationOptions options, string authenticationScheme, ClaimsPrincipal principal, AuthenticationProperties properties) : base(context, options) { AuthenticationScheme = authenticationScheme; Principal = principal; Properties = properties; }
/// <summary> /// Initializes a <see cref="GoogleAuthenticatedContext"/> /// </summary> /// <param name="context">The OWIN environment</param> /// <param name="identity">The <see cref="ClaimsIdentity"/> representing the user</param> /// <param name="properties">A property bag for common authentication properties</param> /// <param name="responseMessage"></param> /// <param name="attributeExchangeProperties"></param> public GoogleAuthenticatedContext( IOwinContext context, ClaimsIdentity identity, AuthenticationProperties properties, XElement responseMessage, IDictionary<string, string> attributeExchangeProperties) : base(context) { Identity = identity; Properties = properties; ResponseMessage = responseMessage; AttributeExchangeProperties = attributeExchangeProperties; }
public async Task<IActionResult> Login(LoginViewModel model) { if (ModelState.IsValid) { var properties = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = new DateTime(2016, 12, 31) }; if (model.Password == _config.NormalUserPassword) { var claims = new[] { new Claim("name", "user"), new Claim(ClaimTypes.Role, "User") }; var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); await HttpContext.Authentication.SignInAsync( CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity), properties); return RedirectToAction("Index", "User"); } if (model.Password == _config.InsiderUserPassword) { var claims = new[] { new Claim("name", "user"), new Claim(ClaimTypes.Role, "Insider") }; var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); await HttpContext.Authentication.SignInAsync( CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity), properties); return RedirectToAction("Index", "User"); } if (model.Password == _config.AdminPassword) { var claims = new[] { new Claim("name", "user"), new Claim(ClaimTypes.Role, "Admin") }; var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); await HttpContext.Authentication.SignInAsync( CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity), properties); return RedirectToAction("Index", "User"); } ModelState.AddModelError("Password", "Hmm, das Passwort scheint ungültig zu sein. Bitte versuche es mit dem richtigen Passwort noch einmal."); } return View(model); }
/// <summary> /// Validates whether Properties are the same as the provided ones from action result containing such property. /// </summary> /// <param name="actionResult">Action result with Properties.</param> /// <param name="properties">Expected authentication properties.</param> /// <param name="failedValidationAction">Action to call in case of failed validation.</param> public static void ValidateAuthenticationProperties( dynamic actionResult, AuthenticationProperties properties, Action<string, string, string> failedValidationAction) { var actualProperties = (AuthenticationProperties)TryGetAuthenticationProperties(actionResult); if (Reflection.AreNotDeeplyEqual(properties, actualProperties)) { failedValidationAction( "authentication properties", "to be the same as the provided one", "instead received different result"); } }
public async Task CookieSignInAsync(User user, bool isPersistent) { await CookieSignOutCurrentUserAsync(); var claims = new List<Claim> { new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()), new Claim(ClaimTypes.Name, user.UserName) }; var identity = new ClaimsIdentity(claims); var principal = new ClaimsPrincipal(identity); var context = _accessor.HttpContext; var props = new AuthenticationProperties{ IsPersistent = isPersistent }; await context.Authentication.SignInAsync(Scheme, principal, props); }
public AuthPropertiesTokenCache(AuthenticationProperties authProperties) : base() { _authProperties = authProperties; BeforeAccess = BeforeAccessNotification; AfterAccess = AfterAccessNotification; BeforeWrite = BeforeWriteNotification; string cachedTokensText; if (authProperties.Items.TryGetValue(TokenCacheKey, out cachedTokensText)) { var cachedTokens = Convert.FromBase64String(cachedTokensText); Deserialize(cachedTokens); } }
public override async Task SignInAsync([NotNull] string authenticationScheme, [NotNull] ClaimsPrincipal principal, AuthenticationProperties properties) { var handler = HttpAuthenticationFeature.Handler; var signInContext = new SignInContext(authenticationScheme, principal, properties?.Items); if (handler != null) { await handler.SignInAsync(signInContext); } if (!signInContext.Accepted) { throw new InvalidOperationException($"The following authentication scheme was not accepted: {authenticationScheme}"); } }
public override async Task ChallengeAsync([NotNull] string authenticationScheme, AuthenticationProperties properties, ChallengeBehavior behavior) { var handler = HttpAuthenticationFeature.Handler; var challengeContext = new ChallengeContext(authenticationScheme, properties?.Items, behavior); if (handler != null) { await handler.ChallengeAsync(challengeContext); } if (!challengeContext.Accepted) { throw new InvalidOperationException($"The following authentication scheme was not accepted: {authenticationScheme}"); } }
/// <summary> /// Initializes a new instance of <see cref="SignOutResult"/> with the /// specified authentication schemes and <paramref name="properties"/>. /// </summary> /// <param name="authenticationSchemes">The authentication scheme to use when signing out the user.</param> /// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the sign-out operation.</param> public SignOutResult(IList<string> authenticationSchemes, AuthenticationProperties properties) { if (authenticationSchemes == null) { throw new ArgumentNullException(nameof(authenticationSchemes)); } if (authenticationSchemes.Count == 0) { throw new ArgumentException(Resources.MustSpecifyAtLeastOneAuthenticationScheme, nameof(authenticationSchemes)); } AuthenticationSchemes = authenticationSchemes; Properties = properties; }
public static AuthenticationProperties GetAuthenticationProperties() { var authenticationProperties = new AuthenticationProperties { AllowRefresh = true, ExpiresUtc = new DateTimeOffset(new DateTime(2016, 1, 1, 1, 1, 1)), IsPersistent = true, IssuedUtc = new DateTimeOffset(new DateTime(2015, 1, 1, 1, 1, 1)), RedirectUri = "test" }; authenticationProperties.Items.Add("TestKeyItem", "TestValueItem"); authenticationProperties.Items.Add("AnotherTestKeyItem", "AnotherTestValueItem"); return authenticationProperties; }
/// <summary> /// Initializes a new instance of <see cref="SignInResult"/> with the /// specified authentication scheme and <paramref name="properties"/>. /// </summary> /// <param name="authenticationScheme">The authentication schemes to use when signing in the user.</param> /// <param name="principal">The claims principal containing the user claims.</param> /// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the sign-in operation.</param> public SignInResult(string authenticationScheme, ClaimsPrincipal principal, AuthenticationProperties properties) { if (authenticationScheme == null) { throw new ArgumentNullException(nameof(authenticationScheme)); } if (principal == null) { throw new ArgumentNullException(nameof(principal)); } AuthenticationScheme = authenticationScheme; Principal = principal; Properties = properties; }
public void CanStoreMultipleTokens() { var props = new AuthenticationProperties(); var tokens = new List<AuthenticationToken>(); var tok1 = new AuthenticationToken { Name = "One", Value = "1" }; var tok2 = new AuthenticationToken { Name = "Two", Value = "2" }; var tok3 = new AuthenticationToken { Name = "Three", Value = "3" }; tokens.Add(tok1); tokens.Add(tok2); tokens.Add(tok3); props.StoreTokens(tokens); Assert.Equal("1", props.GetTokenValue("One")); Assert.Equal("2", props.GetTokenValue("Two")); Assert.Equal("3", props.GetTokenValue("Three")); Assert.Equal(3, props.GetTokens().Count()); }
public void CanRoundTripEmptyPrincipal() { var serializer = new TicketSerializer(); var properties = new AuthenticationProperties(); properties.RedirectUri = "bye"; var ticket = new AuthenticationTicket(new ClaimsPrincipal(), properties, "Hello"); using (var stream = new MemoryStream()) using (var writer = new BinaryWriter(stream)) using (var reader = new BinaryReader(stream)) { serializer.Write(writer, ticket); stream.Position = 0; var readTicket = serializer.Read(reader); Assert.Equal(0, readTicket.Principal.Identities.Count()); Assert.Equal("bye", readTicket.Properties.RedirectUri); Assert.Equal("Hello", readTicket.AuthenticationScheme); } }
public void CanRoundTripBootstrapContext() { var serializer = new TicketSerializer(); var properties = new AuthenticationProperties(); var ticket = new AuthenticationTicket(new ClaimsPrincipal(), properties, "Hello"); ticket.Principal.AddIdentity(new ClaimsIdentity("misc") { BootstrapContext = "bootstrap" }); using (var stream = new MemoryStream()) using (var writer = new BinaryWriter(stream)) using (var reader = new BinaryReader(stream)) { serializer.Write(writer, ticket); stream.Position = 0; var readTicket = serializer.Read(reader); Assert.Equal(1, readTicket.Principal.Identities.Count()); Assert.Equal("misc", readTicket.Principal.Identity.AuthenticationType); Assert.Equal("bootstrap", readTicket.Principal.Identities.First().BootstrapContext); } }
public override async Task ChallengeAsync(string authenticationScheme, AuthenticationProperties properties, ChallengeBehavior behavior) { if (string.IsNullOrEmpty(authenticationScheme)) { throw new ArgumentException(nameof(authenticationScheme)); } var handler = HttpAuthenticationFeature.Handler; var challengeContext = new ChallengeContext(authenticationScheme, properties?.Items, behavior); if (handler != null) { await handler.ChallengeAsync(challengeContext); } if (!challengeContext.Accepted) { throw new InvalidOperationException($"No authentication handler is configured to handle the scheme: {authenticationScheme}"); } }
public async Task<IActionResult> Ntlm(string returnUrl = null) { if (this.User.Identity.IsAuthenticated == false) { var defaultProperties = new AuthenticationProperties() { RedirectUri = returnUrl }; var authContext = new Http.Features.Authentication.AuthenticateContext(ActiveDirectoryOptions.DefaultAuthenticationScheme); await HttpContext.Authentication.AuthenticateAsync(authContext); if (!authContext.Accepted || authContext.Principal == null) { return new UnauthorizedResult(); } } if (string.IsNullOrWhiteSpace(returnUrl)) return new OkResult(); else return Redirect(returnUrl); }
public void SubsequentStoreTokenDeletesPreviousTokens() { var props = new AuthenticationProperties(); var tokens = new List<AuthenticationToken>(); var tok1 = new AuthenticationToken { Name = "One", Value = "1" }; var tok2 = new AuthenticationToken { Name = "Two", Value = "2" }; var tok3 = new AuthenticationToken { Name = "Three", Value = "3" }; tokens.Add(tok1); tokens.Add(tok2); tokens.Add(tok3); props.StoreTokens(tokens); props.StoreTokens(new[] { new AuthenticationToken { Name = "Zero", Value = "0" } }); Assert.Equal("0", props.GetTokenValue("Zero")); Assert.Equal(null, props.GetTokenValue("One")); Assert.Equal(null, props.GetTokenValue("Two")); Assert.Equal(null, props.GetTokenValue("Three")); Assert.Equal(1, props.GetTokens().Count()); }
public JsonResult UserLogin(string username, string password) { var userLogin = UserLoginRepo.NewInstance.Filter.UserLogin(username, password).Get.FirstOrDefault(); if (userLogin == null || !BC.Verify(password, userLogin.Password)) { return(Json(new { result = false })); } else { //Token üretiliyor. TokenHandler tokenHandler = new TokenHandler(configuration); Token.Token token = tokenHandler.CreateAccessToken(userLogin); //Refresh token Users tablosuna işleniyor. userLogin.RefreshToken = token.RefreshToken; userLogin.RefreshTokenEndDate = token.Expiration.AddMinutes(3); var updateRefresh = UserLoginRepo.NewInstance.Do.Update(userLogin); var claims = new List <Claim> { new Claim(ClaimTypes.Sid, userLogin.UserId.ToString()), new Claim(ClaimTypes.NameIdentifier, userLogin.RefreshToken), new Claim(ClaimTypes.Name, userLogin.Name + " " + userLogin.Surname), new Claim(ClaimTypes.Email, userLogin.Email) }; var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); var principal = new ClaimsPrincipal(identity); var props = new AuthenticationProperties(); HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, props); return(Json(new { result = true })); } }
public IActionResult GoogleOpenIdConnectChallenge([FromQuery] string?ReturnUrl) { ReturnUrl ??= RETURN_URL_DEFAULT; if (!Url.IsLocalUrl(ReturnUrl)) { return(BadRequest($"\"{ReturnUrl}\" is not a local url")); } AuthenticationProperties authenticationProperties = new AuthenticationProperties { RedirectUri = ReturnUrl, }; bool isAuthenticated = User.Identity?.IsAuthenticated ?? false; if (isAuthenticated) { return(LocalRedirect(authenticationProperties.RedirectUri)); } else { return(Challenge(authenticationProperties, new string[] { GoogleOpenIdConnectDefaults.AuthenticationScheme })); } }
public async Task <IActionResult> Index(LoginRequest request) { if (!ModelState.IsValid) { return(View()); } var result = await _userApiClient.Authenticate(request); var userPrincipal = this.ValidateToken(result.ResultDataObject); var authProperties = new AuthenticationProperties() { ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(30), IsPersistent = false }; //Set session để lưu giữ khi đăng nhập thành công, nhằm check xem user đã đăng nhập hay chưa, nếu chưa sẽ chỉ hiện trang đăng nhập HttpContext.Session.SetString("Token", result.ResultDataObject); await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, userPrincipal, authProperties); return(RedirectToAction("Index", "Home")); }
/// <InheritDoc /> public Task ChallengeAsync(AuthenticationProperties properties) { if (properties == null) { throw new ArgumentNullException(nameof(properties)); } // Don't serialize the return url twice, move it to our location. var redirectUri = properties.RedirectUri; properties.RedirectUri = null; var requestData = context.ToHttpRequestData(null); var result = SignInCommand.Run( null, redirectUri, requestData, options, properties.Items); result.Apply(context, dataProtector, scheme.Name); return Task.CompletedTask; }
public async Task <IActionResult> SignIn(string provider, string redirectUrl) { // Note: the "provider" parameter corresponds to the external // authentication provider choosen by the user agent. if (string.IsNullOrWhiteSpace(provider)) { return(BadRequest()); } if (!await HttpContext.IsProviderSupportedAsync(provider)) { return(BadRequest()); } string url = $"{Request.Scheme}://{Request.Host}{Request.PathBase}{Request.Path}-callback?provider={provider}" + $"&redirectUrl={redirectUrl}"; _logger.LogInformation($"SignIn-url:{url}"); var properties = new AuthenticationProperties { RedirectUri = url }; properties.Items[LoginProviderKey] = provider; return(Challenge(properties, provider)); }
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { if (!context.OwinContext.Response.Headers.ContainsKey("Access-Control-Allow-Origin")) { context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" }); } var user = new UserService().GetIdentityUserByLogin(context.UserName, context.Password); if (user == null) { context.SetError("invalid_grant", "Invalid username and/or password!"); return; } var identity = ToClaimsIdentity(context.Options.AuthenticationType, user); var props = new AuthenticationProperties(new Dictionary <string, string> { { "userName", user.UserName } }); var ticket = new AuthenticationTicket(identity, props); context.Validated(ticket); }
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { var userManager = context.OwinContext.GetUserManager <ApplicationUserManager>(); ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password); if (user == null) { context.SetError("invalid_grant", "Имя пользователя или пароль указаны неправильно."); return; } ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, OAuthDefaults.AuthenticationType); ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager, CookieAuthenticationDefaults.AuthenticationType); AuthenticationProperties properties = CreateProperties(user.UserName); AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties); context.Validated(ticket); context.Request.Context.Authentication.SignIn(cookiesIdentity); }
public async Task <IActionResult> Register(string client_assertion) { // Tell the AAD B2C middleware to invoke a specific policy. // NOTE: this resets the scope and response type so no authorization code is requested from this flow, // see https://github.com/aspnet/AspNetCore/blob/release/3.1/src/Azure/AzureAD/Authentication.AzureADB2C.UI/src/AzureAdB2COpenIDConnectEventHandlers.cs#L35-L36. var authenticationProperties = new AuthenticationProperties(); authenticationProperties.RedirectUri = Url.Action("Registered", "Account"); if (!string.IsNullOrWhiteSpace(client_assertion)) { // Use the client assertion flow and pass the client_assertion through. authenticationProperties.Items[AzureADB2CDefaults.PolicyKey] = this.invitationClientAssertionPolicyId; authenticationProperties.Items[OpenIdConnectParameterNames.ClientAssertion] = client_assertion; } else { // Use the invitation code flow. authenticationProperties.Items[AzureADB2CDefaults.PolicyKey] = this.invitationCodePolicyId; } await HttpContext.ChallengeAsync(AzureADB2CDefaults.AuthenticationScheme, authenticationProperties); return(new EmptyResult()); }
public async Task ExecuteAsync_InvokesSignOutAsyncOnAllConfiguredSchemes() { // Arrange var authProperties = new AuthenticationProperties(); var httpContext = new Mock <HttpContext>(); var auth = new Mock <IAuthenticationService>(); auth .Setup(c => c.SignOutAsync(httpContext.Object, "Scheme1", authProperties)) .Returns(Task.CompletedTask) .Verifiable(); auth .Setup(c => c.SignOutAsync(httpContext.Object, "Scheme2", authProperties)) .Returns(Task.CompletedTask) .Verifiable(); httpContext.Setup(c => c.RequestServices).Returns(CreateServices(auth.Object)); var result = new SignOutResult(new[] { "Scheme1", "Scheme2" }, authProperties); // Act await((IResult)result).ExecuteAsync(httpContext.Object); // Assert auth.Verify(); }
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { using (UserManager <IdentityUser> userManager = _userManagerFactory()) { IdentityUser user = await userManager.FindAsync(context.UserName, context.Password); if (user == null) { context.SetError("invalid_grant", "The user name or password is incorrect."); return; } ClaimsIdentity oAuthIdentity = await userManager.CreateIdentityAsync(user, context.Options.AuthenticationType); ClaimsIdentity cookiesIdentity = await userManager.CreateIdentityAsync(user, CookieAuthenticationDefaults.AuthenticationType); AuthenticationProperties properties = CreateProperties(user.UserName); AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties); context.Validated(ticket); context.Request.Context.Authentication.SignIn(cookiesIdentity); } }
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { var userManager = HttpContext.Current.GetOwinContext().GetUserManager <INAB.ApplicationUserManager>(); AppUser user = await userManager.FindAsync(context.UserName, context.Password); if (user == null) { context.SetError("invalid_grant", "The user name or password is incorrect."); return; } ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, OAuthDefaults.AuthenticationType); ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager, CookieAuthenticationDefaults.AuthenticationType); AuthenticationProperties properties = CreateProperties(oAuthIdentity); AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties); context.Validated(ticket); context.Request.Context.Authentication.SignIn(cookiesIdentity); }
protected override async Task <AuthenticationTicket> AuthenticateCoreAsync() { AuthenticationProperties properties = null; try { string state = null; string code = null; IReadableStringCollection query = Request.Query; IList <string> values; values = query.GetValues("state"); if (values != null && values.Count == 1) { state = values[0]; } properties = Options.StateDataFormat.Unprotect(state); if (properties == null) { return(null); } values = query.GetValues("error"); if (values != null && values.Count == 1) { return(new AuthenticationTicket(null, properties)); } values = query.GetValues("code"); if (values != null && values.Count == 1) { code = values[0]; } // OAuth2 10.12 CSRF if (!ValidateCorrelationId(properties, _logger)) { return(new AuthenticationTicket(null, properties)); } string requestPrefix = Request.Scheme + "://" + Request.Host; string redirectUri = requestPrefix + Request.PathBase + Options.CallbackPath; var body = new List <KeyValuePair <string, string> > { new KeyValuePair <string, string>("grant_type", "authorization_code"), new KeyValuePair <string, string>("code", code), new KeyValuePair <string, string>("client_id", Options.ClientId), new KeyValuePair <string, string>("client_secret", Options.ClientSecret), new KeyValuePair <string, string>("redirect_uri", redirectUri) }; // Request the token var tokenResponse = await _httpClient.PostAsync(TokenEndpoint, new FormUrlEncodedContent(body)); tokenResponse.EnsureSuccessStatusCode(); string content = await tokenResponse.Content.ReadAsStringAsync(); // Deserializes the token response var response = JsonConvert.DeserializeObject <JObject>(content); string accessToken = response.Value <string>("access_token"); _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var userResponse = await _httpClient.GetAsync(UserInfoEndpoint); var userContent = await userResponse.Content.ReadAsStringAsync(); JObject userJson = null; if (userResponse.IsSuccessStatusCode) { userJson = JObject.Parse(userContent); } var context = new IntercomAuthenticatedContext(Context, accessToken, userJson); context.Identity = new ClaimsIdentity( Options.AuthenticationType, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType); if (!String.IsNullOrEmpty(context.UserId)) { context.Identity.AddClaim( new Claim(ClaimTypes.NameIdentifier, context.UserId, XmlSchemaString, Options.AuthenticationType)); } if (!String.IsNullOrEmpty(context.Email)) { context.Identity.AddClaim( new Claim(ClaimTypes.Email, context.Email, XmlSchemaString, Options.AuthenticationType)); } context.Properties = properties; await Options.Provider.Authenticated(context); return(new AuthenticationTicket(context.Identity, context.Properties)); } catch (Exception ex) { _logger.WriteError("Authentication failed", ex); return(new AuthenticationTicket(null, properties)); } }
protected override async Task HandleForbiddenAsync(AuthenticationProperties properties) { Response.ContentType = "application/json"; Response.StatusCode = StatusCodes.Status403Forbidden; await Response.WriteAsync(JsonConvert.SerializeObject((new ApiResponse(StatusCode.CODE403)).MessageModel)); }
private void ProcessLoginCallbackForSaml2p(AuthenticateResult externalResult, List <Claim> localClaims, AuthenticationProperties localSignInProps) { }
public async Task <IActionResult> Callback() { // read external identity from the temporary cookie var result = await HttpContext.AuthenticateAsync(IdentityConstants.ExternalScheme); if (result?.Succeeded != true) { throw new Exception("External authentication error"); } if (_logger.IsEnabled(LogLevel.Debug)) { var externalClaims = result.Principal.Claims.Select(c => $"{c.Type}: {c.Value}"); _logger.LogDebug("External claims: {@claims}", externalClaims); } // lookup our user and external provider info var(user, provider, providerUserId, claims) = await FindUserFromExternalProviderAsync(result); if (user == null) { // this might be where you might initiate a custom workflow for user registration // in this sample we don't show how that would be done, as our sample implementation // simply auto-provisions new external user user = await AutoProvisionUserAsync(provider, providerUserId, claims); } // this allows us to collect any additonal claims or properties // for the specific prtotocols used and store them in the local auth cookie. // this is typically used to store data needed for signout from those protocols. var additionalLocalClaims = new List <Claim>(); var localSignInProps = new AuthenticationProperties(); ProcessLoginCallbackForOidc(result, additionalLocalClaims, localSignInProps); ProcessLoginCallbackForWsFed(result, additionalLocalClaims, localSignInProps); ProcessLoginCallbackForSaml2p(result, additionalLocalClaims, localSignInProps); // issue authentication cookie for user // we must issue the cookie maually, and can't use the SignInManager because // it doesn't expose an API to issue additional claims from the login workflow var principal = await _signInManager.CreateUserPrincipalAsync(user); additionalLocalClaims.AddRange(principal.Claims); var name = principal.FindFirst(JwtClaimTypes.Name)?.Value ?? user.Id; await HttpContext.SignInAsync(user.Id, name, provider, localSignInProps, additionalLocalClaims.ToArray()); // delete temporary cookie used during external authentication await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); // retrieve return URL var returnUrl = result.Properties.Items["returnUrl"] ?? "~/"; // check if external login is in the context of an OIDC request var context = await _interaction.GetAuthorizationContextAsync(returnUrl); await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.Id, name, true, context?.ClientId)); if (context != null) { if (await _clientStore.IsPkceClientAsync(context.ClientId)) { // if the client is PKCE then we assume it's native, so this change in how to // return the response is for better UX for the end user. return(View("Redirect", new RedirectViewModel { RedirectUrl = returnUrl })); } } return(Redirect(returnUrl)); }
/// <summary> /// Handles the <see cref="MsalUiRequiredException"/>. /// </summary> /// <param name="context">Context provided by ASP.NET Core.</param> public override void OnException(ExceptionContext context) { if (context != null) { MsalUiRequiredException?msalUiRequiredException = FindMsalUiRequiredExceptionIfAny(context.Exception); if (msalUiRequiredException != null && IncrementalConsentAndConditionalAccessHelper.CanBeSolvedByReSignInOfUser(msalUiRequiredException)) { // the users cannot provide both scopes and ScopeKeySection at the same time if (!string.IsNullOrWhiteSpace(ScopeKeySection) && Scopes != null && Scopes.Length > 0) { throw new InvalidOperationException( string.Format( CultureInfo.InvariantCulture, IDWebErrorMessage.ProvideEitherScopeKeySectionOrScopes, nameof(ScopeKeySection), nameof(Scopes))); } // Do not re-use the property Scopes. For more info: https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/issues/273 string[]? incrementalConsentScopes; // If the user wishes us to pick the Scopes from a particular config setting. if (!string.IsNullOrWhiteSpace(ScopeKeySection)) { // Load the injected IConfiguration IConfiguration?configuration = context.HttpContext.RequestServices.GetService <IConfiguration>(); if (configuration == null) { throw new InvalidOperationException( string.Format( CultureInfo.InvariantCulture, IDWebErrorMessage.ScopeKeySectionIsProvidedButNotPresentInTheServicesCollection, nameof(ScopeKeySection))); } incrementalConsentScopes = new string[] { configuration.GetValue <string>(ScopeKeySection) }; if (Scopes != null && Scopes.Length > 0 && incrementalConsentScopes.Length > 0) { throw new InvalidOperationException(IDWebErrorMessage.NoScopesProvided); } } else { incrementalConsentScopes = Scopes; } HttpRequest httpRequest; ClaimsPrincipal user; HttpContext httpContext = context.HttpContext; lock (httpContext) { httpRequest = httpContext.Request; user = httpContext.User; } AuthenticationProperties properties = IncrementalConsentAndConditionalAccessHelper.BuildAuthenticationProperties( incrementalConsentScopes, msalUiRequiredException, user, UserFlow); if (IsAjaxRequest(httpRequest) && (!string.IsNullOrEmpty(httpRequest.Headers[Constants.XReturnUrl]) || !string.IsNullOrEmpty(httpRequest.Query[Constants.XReturnUrl]))) { string redirectUri = !string.IsNullOrEmpty(httpRequest.Headers[Constants.XReturnUrl]) ? httpRequest.Headers[Constants.XReturnUrl] : httpRequest.Query[Constants.XReturnUrl]; UrlHelper urlHelper = new UrlHelper(context); if (urlHelper.IsLocalUrl(redirectUri)) { properties.RedirectUri = redirectUri; } } if (AuthenticationScheme != null) { context.Result = new ChallengeResult(AuthenticationScheme, properties); } else { context.Result = new ChallengeResult(properties); } } } base.OnException(context); }
protected virtual async Task <AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { using (var user = JsonDocument.Parse("{}")) { var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, user.RootElement); await Events.CreatingTicket(context); return(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name)); } }
public Task ForbidAsync(AuthenticationProperties properties) { Context.Response.StatusCode = 403; return(Task.CompletedTask); }
protected override async Task <AuthenticationTicket> AuthenticateCoreAsync() { AuthenticationProperties properties = null; try { string code = null; string state = null; var query = Request.Query; var values = query.GetValues("code"); if (values != null && values.Count == 1) { code = values[0]; } values = query.GetValues("state"); if (values != null && values.Count == 1) { state = values[0]; } properties = Options.StateDataFormat.Unprotect(state); if (properties == null) { return(null); } // OAuth2 10.12 CSRF if (!ValidateCorrelationId(properties, _logger)) { return(new AuthenticationTicket(null, properties)); } var requestPrefix = Request.Scheme + "://" + this.GetHostName(); var redirectUri = requestPrefix + Request.PathBase + Options.CallbackPath; // Build up the body for the token request var body = new List <KeyValuePair <string, string> > { new KeyValuePair <string, string>("grant_type", "authorization_code"), new KeyValuePair <string, string>("code", code), new KeyValuePair <string, string>("redirect_uri", redirectUri), new KeyValuePair <string, string>("client_id", Options.ClientId), new KeyValuePair <string, string>("client_secret", Options.ClientSecret) }; // Request the token var tokenResponse = await _httpClient.PostAsync(TokenEndpoint, new FormUrlEncodedContent(body)); tokenResponse.EnsureSuccessStatusCode(); var text = await tokenResponse.Content.ReadAsStringAsync(); // Deserializes the token response dynamic response = JsonConvert.DeserializeObject <dynamic>(text); var accessToken = (string)response.access_token; var expires = (string)response.expires_in; // Get the LinkedIn user var userInfoEndpoint = UserInfoEndpoint + "~:(" + string.Join(",", Options.ProfileFields.Distinct().ToArray()) + ")" + "?oauth2_access_token=" + Uri.EscapeDataString(accessToken); var userRequest = new HttpRequestMessage(HttpMethod.Get, userInfoEndpoint); userRequest.Headers.Add("x-li-format", "json"); var graphResponse = await _httpClient.SendAsync(userRequest, Request.CallCancelled); graphResponse.EnsureSuccessStatusCode(); text = await graphResponse.Content.ReadAsStringAsync(); var user = JObject.Parse(text); var context = new LinkedInAuthenticatedContext(Context, user, accessToken, expires) { Identity = new ClaimsIdentity( Options.AuthenticationType, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType) }; if (!string.IsNullOrEmpty(context.Id)) { context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, XmlSchemaString, Options.AuthenticationType)); } if (!string.IsNullOrEmpty(context.Email)) { context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, XmlSchemaString, Options.AuthenticationType)); } if (!string.IsNullOrEmpty(context.GivenName)) { context.Identity.AddClaim(new Claim(ClaimTypes.GivenName, context.GivenName, XmlSchemaString, Options.AuthenticationType)); } if (!string.IsNullOrEmpty(context.FamilyName)) { context.Identity.AddClaim(new Claim(ClaimTypes.Surname, context.FamilyName, XmlSchemaString, Options.AuthenticationType)); } if (!string.IsNullOrEmpty(context.Name)) { context.Identity.AddClaim(new Claim(ClaimTypes.Name, context.Name, XmlSchemaString, Options.AuthenticationType)); context.Identity.AddClaim(new Claim("urn:linkedin:name", context.Name, XmlSchemaString, Options.AuthenticationType)); } if (!string.IsNullOrEmpty(context.Industry)) { context.Identity.AddClaim(new Claim("urn:linkedin:industry", context.Industry, XmlSchemaString, Options.AuthenticationType)); } if (!string.IsNullOrEmpty(context.Positions)) { context.Identity.AddClaim(new Claim("urn:linkedin:positions", context.Positions, XmlSchemaString, Options.AuthenticationType)); } if (!string.IsNullOrEmpty(context.Summary)) { context.Identity.AddClaim(new Claim("urn:linkedin:summary", context.Summary, XmlSchemaString, Options.AuthenticationType)); } if (!string.IsNullOrEmpty(context.Headline)) { context.Identity.AddClaim(new Claim("urn:linkedin:headline", context.Headline, XmlSchemaString, Options.AuthenticationType)); } if (!string.IsNullOrEmpty(context.Link)) { context.Identity.AddClaim(new Claim("urn:linkedin:url", context.Link, XmlSchemaString, Options.AuthenticationType)); } if (!string.IsNullOrEmpty(context.AccessToken)) { context.Identity.AddClaim(new Claim("urn:linkedin:accesstoken", context.AccessToken, XmlSchemaString, Options.AuthenticationType)); } context.Properties = properties; await Options.Provider.Authenticated(context); return(new AuthenticationTicket(context.Identity, context.Properties)); } catch (Exception ex) { _logger.WriteError(ex.Message); } return(new AuthenticationTicket(null, properties)); }
/// <summary> /// The core authentication logic which must be provided by the handler. Will be invoked at most /// once per request. Do not call directly, call the wrapping Authenticate method instead. /// </summary> /// <returns>The ticket data provided by the authentication logic.</returns> protected override async Task <AuthenticationTicket> AuthenticateCoreAsync() { if (!this.ShouldAuthenticate()) { return(null); } try { var query = this.Request.Query; // Try to refresh token if a cookie exists if (this.Context.Authentication.User != null && !this.Context.Authentication.User.Identity.IsAuthenticated) { var refreshCookie = this.Context.Request.Cookies.FirstOrDefault(x => x.Key == $"{this.Options.CookieConfiguration.Name}_RT"); if (refreshCookie.Value != null) { var refreshTokenResponse = await this.Options.TicketHandler.RefreshTokenAsync(this.Context, this.Options, refreshCookie.Value, this.Options.RedirectUri); if (refreshTokenResponse != null) { // Sign in as sentinel identity var props = new AuthenticationProperties() { RedirectUri = this.Context.Request.Uri.ToString() }; var ticket = await this.Options.TicketHandler.SignInAsync(this.Context, this.Options, refreshTokenResponse, props); await this.Options.Events.OnTokenRefreshed(this.Context, ticket, this.Options); return(ticket); } this.Options.Logger.WriteError("Refresh token found, but was unable to use it to retrieve a new access token"); // Delete refresh token if it didnt work to prevent retries with an invalid token this.Context.Response.Cookies.Delete($"{this.Options.CookieConfiguration.Name}_RT", new CookieOptions() { Domain = this.Request.Uri.Host, Secure = this.Request.IsSecure }); } } // Check for errors var error = query["error"]; if (!string.IsNullOrEmpty(error)) { var failureMessage = new StringBuilder(); failureMessage.Append(error); var errorDescription = query["error_description"]; if (!string.IsNullOrEmpty(errorDescription)) { failureMessage.Append(";Description=").Append(errorDescription); } var errorUri = query["error_uri"]; if (!string.IsNullOrEmpty(errorUri)) { failureMessage.Append(";Uri=").Append(errorUri); } this.Options.Logger.WriteError(failureMessage.ToString()); await this.Options.Events.OnAuthorizeError(this.Context, this.Options, error, errorDescription, errorUri); return(null); } string code = null; string state = null; // Parse code var codeQueryParam = query.GetValues("code"); if (codeQueryParam != null && codeQueryParam.Count == 1) { code = codeQueryParam[0]; } // Parse state var stateQueryParam = query.GetValues("state"); if (stateQueryParam != null && stateQueryParam.Count == 1) { state = stateQueryParam[0]; } // Dont continue if code is null if (string.IsNullOrEmpty(code)) { return(null); } // Extract state var properties = this.Options.StateDataFormat.Unprotect(state); if (properties == null) { await this.Options.Events.OnStateError(this.Context, this.Options, properties, "invalid_state"); return(null); } // Validate state to prevent CSRF (See https://tools.ietf.org/html/rfc6749#section-10.12) if (!this.ValidateCorrelationId(properties, this.Options.Logger)) { this.Options.Logger.WriteError("The CSRF Correlation ID is invalid"); await this.Options.Events.OnStateError(this.Context, this.Options, properties, "invalid_correlation_id"); return(null); } var tokenResponse = await this.Options.TicketHandler.ExchangeCodeAsync(this.Context, this.Options, code, this.Options.RedirectUri); if (string.IsNullOrEmpty(tokenResponse.AccessToken)) { this.Options.Logger.WriteError("No access token was included in the response"); await this.Options.Events.OnTokenError(this.Context, this.Options, tokenResponse); return(null); } return(await this.Options.TicketHandler.SignInAsync(this.Context, this.Options, tokenResponse, properties)); } catch (Exception ex) { this.Options.Logger.WriteError("Authentication failed", ex); await this.Options.Events.OnException(this.Context, this.Options, ex); return(null); } }
public Task ChallengeAsync(AuthenticationProperties properties) { Context.Response.Redirect("/login"); return(Task.CompletedTask); }
private void ProcessLoginCallbackForOidc(AuthenticateResult externalResult, List <Claim> localClaims, AuthenticationProperties localSignInProps) { // if the external system sent a session id claim, copy it over // so we can use it for single sign-out var sid = externalResult.Principal.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId); if (sid != null) { localClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value)); } // if the external provider issued an id_token, we'll keep it for signout var id_token = externalResult.Properties.GetTokenValue("id_token"); if (id_token != null) { localSignInProps.StoreTokens(new[] { new AuthenticationToken { Name = "id_token", Value = id_token } }); } }
/// <summary> /// This is called when a Challenge is issued to this authentication schema /// </summary> /// <param name="properties">These are not used in this middleware</param> /// <returns>A completed task to indicate that the challenge was handled</returns> protected override Task HandleChallengeAsync(AuthenticationProperties properties) { Logger.LogInformation("Challenge started"); Response.Redirect(Options.CallbackPath); return(Task.CompletedTask); }
/// <summary>Gets the <see cref="ImgurAuthenticatedContext"/> for the current authentication session.</summary> /// <param name="authenticationResponse">The <see cref="AuthenticationResponse"/> returned by imgur.</param> /// <param name="identity">The <see cref="ClaimsIdentity"/> for the identity of the user.</param> /// <param name="properties">The <see cref="AuthenticationProperties"/> for the current authentication session.</param> /// <returns>The <see cref="ImgurAuthenticatedContext"/> for the current authentication session.</returns> private ImgurAuthenticatedContext GetImgurAuthenticatedContext(AuthenticationResponse authenticationResponse, ClaimsIdentity identity, AuthenticationProperties properties) { var context = new ImgurAuthenticatedContext(this.Context, this.Options); context.AccessToken = authenticationResponse.AccessToken; context.AccountId = authenticationResponse.AccountId; context.AccountUsername = authenticationResponse.AccountUsername; context.ExpiresIn = authenticationResponse.ExpiresIn; context.Identity = identity; context.Properties = properties; context.RefreshToken = authenticationResponse.RefreshToken; context.Scope = authenticationResponse.Scope; context.TokenType = authenticationResponse.TokenType; return(context); }
/// <summary> /// Creates a <see cref="TokenValidatedContext"/> /// </summary> public TokenValidatedContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options, ClaimsPrincipal principal, AuthenticationProperties properties) : base(context, scheme, options, properties) => Principal = principal;
//public AuthenticationTicket Unprotect(string protectedText) //{ // throw new NotImplementedException(); // //return new AuthenticationTicket(identity, authenticationProperties); //} /// <summary> /// method which is responsible for validation of the JWT and returning and authentication ticket: /// </summary> /// <param name = "protectedText" ></ param > /// < returns ></ returns > public AuthenticationTicket Unprotect(string protectedText) { Microsoft.IdentityModel.Tokens.SecurityToken validatedToken; if (string.IsNullOrWhiteSpace(protectedText)) { throw new ArgumentNullException("protectedText"); } //Fwk.Security.Identity.jwtSecurityProvider sec_provider = null; var tokenHandler = new JwtSecurityTokenHandler(); var jwtSecurityToken = tokenHandler.ReadJwtToken(protectedText); var securityProviderNameClaim = jwtSecurityToken.Claims.FirstOrDefault(c => c.Type == "securityProviderName"); if (securityProviderNameClaim == null) { throw new ArgumentNullException("securityProviderName claims in jwt"); } var sec_provider = helper.get_secConfig().GetByName(securityProviderNameClaim.Value); if (sec_provider == null) { throw new ArgumentNullException("No se encuentra configurado el proveedor (securityProviderName) en securityConfig.json"); } string audienceId = sec_provider.audienceId; string symmetricKeyAsBase64 = sec_provider.audienceSecret; var keyByteArray = TextEncodings.Base64Url.Decode(symmetricKeyAsBase64); var securityKey = new SymmetricSecurityKey(keyByteArray); var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature); //TODO : CustomJwtFormat Esta lista de issuers debe ser flexible ///Establezco los issuers validos var issuers = new List <string>() { "http://localhost:44345/" }; var validationParams = new TokenValidationParameters() { ValidAudience = sec_provider.audienceId, ValidIssuers = issuers, ValidateLifetime = true, ValidateAudience = true, ValidateIssuer = true, RequireSignedTokens = true, RequireExpirationTime = true, ValidateIssuerSigningKey = true, ClockSkew = TimeSpan.Zero, //IssuerSigningKeys = DefaultX509Key_Public_2048 IssuerSigningKey = signingCredentials.Key }; try { var principal = tokenHandler.ValidateToken(protectedText, validationParams, out validatedToken); var identity = principal.Identities.First(); // Fill out the authenticationProperties issued and expires times if the equivalent claims are in the JWT var authenticationProperties = new AuthenticationProperties(); //issued if (validatedToken.ValidFrom != DateTime.MinValue) { authenticationProperties.IssuedUtc = validatedToken.ValidFrom.ToUniversalTime(); } //expires if (validatedToken.ValidTo != DateTime.MinValue) { authenticationProperties.ExpiresUtc = validatedToken.ValidTo.ToUniversalTime(); } return(new AuthenticationTicket(identity, authenticationProperties)); } catch (Exception ex) { //var statusCode = HttpStatusCode.Unauthorized; //return Task<HttpResponseMessage>.Factory.StartNew(() => new HttpResponseMessage(statusCode) { }); var ec = new Fwk.Exceptions.FunctionalException((int)HttpStatusCode.Unauthorized, " No autorizado ", ex); throw ec; } }
public async Task <IActionResult> Callback() { // read external identity from the temporary cookie var result = await HttpContext.AuthenticateAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); if (result?.Succeeded != true) { throw new Exception("External authentication error"); } if (_logger.IsEnabled(LogLevel.Debug)) { var externalClaims = result.Principal.Claims.Select(c => $"{c.Type}: {c.Value}"); _logger.LogDebug("External claims: {@claims}", externalClaims); } // lookup our user and external provider info var(user, provider, providerUserId, claims) = FindUserFromExternalProvider(result); if (user == null) { // this might be where you might initiate a custom workflow for user registration // in this sample we don't show how that would be done, as our sample implementation // simply auto-provisions new external user user = AutoProvisionUser(provider, providerUserId, claims); } // this allows us to collect any additional claims or properties // for the specific protocols used and store them in the local auth cookie. // this is typically used to store data needed for signout from those protocols. var additionalLocalClaims = new List <Claim>(); var localSignInProps = new AuthenticationProperties(); ProcessLoginCallbackForOidc(result, additionalLocalClaims, localSignInProps); //ProcessLoginCallbackForWsFed(result, additionalLocalClaims, localSignInProps); //ProcessLoginCallbackForSaml2p(result, additionalLocalClaims, localSignInProps); // issue authentication cookie for user var isuser = new IdentityServerUser(user.SubjectId) { DisplayName = user.Username, IdentityProvider = provider, AdditionalClaims = additionalLocalClaims }; await HttpContext.SignInAsync(isuser, localSignInProps); // delete temporary cookie used during external authentication await HttpContext.SignOutAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); // retrieve return URL var returnUrl = result.Properties.Items["returnUrl"] ?? "~/"; // check if external login is in the context of an OIDC request var context = await _interaction.GetAuthorizationContextAsync(returnUrl); await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.SubjectId, user.Username, true, context?.ClientId)); if (context != null) { if (await _clientStore.IsPkceClientAsync(context.ClientId)) { // if the client is PKCE then we assume it's native, so this change in how to // return the response is for better UX for the end user. return(this.LoadingPage("Redirect", returnUrl)); } } return(Redirect(returnUrl)); }
public async Task <IHttpActionResult> GetExternalLogin(string provider, string error = null) { if (error != null) { return(Redirect(Url.Content("~/") + "#error=" + Uri.EscapeDataString(error))); } if (!User.Identity.IsAuthenticated) { return(new ChallengeResult(provider, this)); } ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity); if (externalLogin == null || externalLogin.LoginProvider != provider) { Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType); return(Redirect(Url.Content("~/"))); } IdentityAccount account = await _userManager.FindAsync(new UserLoginInfo(externalLogin.LoginProvider, externalLogin.ProviderKey)); if (account == null) { IdentityResult result = null; account = await _userManager.FindByNameAsync(externalLogin.UserName); if (account == null) { account = new IdentityAccount { UserName = externalLogin.UserName }; result = await _userManager.CreateAsync(account); if (!result.Succeeded) { return(InternalServerError()); } } UserLoginInfo login = new UserLoginInfo(externalLogin.LoginProvider, externalLogin.ProviderKey); result = await _userManager.AddLoginAsync(account.Id, login); if (!result.Succeeded) { return(InternalServerError()); } } Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie); ClaimsIdentity oAuthIdentity = await _userManager.CreateIdentityAsync(account, OAuthDefaults.AuthenticationType); ClaimsIdentity cookieIdentity = await _userManager.CreateIdentityAsync(account, CookieAuthenticationDefaults.AuthenticationType); AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(account.UserName); Authentication.SignIn(properties, oAuthIdentity, cookieIdentity); return(Ok()); }
public async Task <IActionResult> Login(LoginInputModel model, string button) { // check if we are in the context of an authorization request var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl); // the user clicked the "cancel" button if (button != "login") { if (context != null) { // if the user cancels, send a result back into IdentityServer as if they // denied the consent (even if this client does not require consent). // this will send back an access denied OIDC error response to the client. await _interaction.GrantConsentAsync(context, ConsentResponse.Denied); // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null if (await _clientStore.IsPkceClientAsync(context.ClientId)) { // if the client is PKCE then we assume it's native, so this change in how to // return the response is for better UX for the end user. return(View("Redirect", new RedirectViewModel { RedirectUrl = model.ReturnUrl })); } return(Redirect(model.ReturnUrl)); } else { // since we don't have a valid context, then we just go back to the home page return(Redirect("~/")); } } if (ModelState.IsValid) { // validate username/password against in-memory store if (_users.ValidateCredentials(model.Username, model.Password)) { var user = _users.FindByUsername(model.Username); await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username, clientId : context?.ClientId)); // only set explicit expiration here if user chooses "remember me". // otherwise we rely upon expiration configured in cookie middleware. AuthenticationProperties props = null; if (AccountOptions.AllowRememberLogin && model.RememberLogin) { props = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration) }; } ; // issue authentication cookie with subject ID and username await HttpContext.SignInAsync(user.SubjectId, user.Username, props); if (context != null) { if (await _clientStore.IsPkceClientAsync(context.ClientId)) { // if the client is PKCE then we assume it's native, so this change in how to // return the response is for better UX for the end user. return(View("Redirect", new RedirectViewModel { RedirectUrl = model.ReturnUrl })); } // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null return(Redirect(model.ReturnUrl)); } // request for a local page if (Url.IsLocalUrl(model.ReturnUrl)) { return(Redirect(model.ReturnUrl)); } else if (string.IsNullOrEmpty(model.ReturnUrl)) { return(Redirect("~/")); } else { // user might have clicked on a malicious link - should be logged throw new Exception("invalid return URL"); } } await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials", clientId : context?.ClientId)); ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage); } // something went wrong, show form with error var vm = await BuildLoginViewModelAsync(model); return(View(vm)); }
protected override async Task <AuthenticationTicket> CreateTicketAsync( [NotNull] ClaimsIdentity identity, [NotNull] AuthenticationProperties properties, [NotNull] string identifier, [NotNull] IReadOnlyDictionary <string, string> attributes) { var principal = new ClaimsPrincipal(identity); var ticket = new AuthenticationTicket(principal, properties, Scheme.Name); // Return the authentication ticket as-is if the user information endpoint has not been set. if (string.IsNullOrEmpty(Options.UserInformationEndpoint)) { Logger.LogInformation("The userinfo request was skipped because no userinfo endpoint was configured."); return(await RunAuthenticatedEventAsync()); } // Return the authentication ticket as-is if the application key has not been set. if (string.IsNullOrEmpty(Options.ApplicationKey)) { Logger.LogInformation("The userinfo request was skipped because no application key was configured."); return(await RunAuthenticatedEventAsync()); } // Note: prior to April 2018, the Steam identifier was prefixed with an HTTP base address. // Since then, the prefix is now an HTTPS address. The following logic supports both prefixes. if (identifier.StartsWith(SteamAuthenticationConstants.Namespaces.Identifier, StringComparison.Ordinal)) { identifier = identifier.Substring(SteamAuthenticationConstants.Namespaces.Identifier.Length); } else if (identifier.StartsWith(SteamAuthenticationConstants.Namespaces.LegacyIdentifier, StringComparison.Ordinal)) { identifier = identifier.Substring(SteamAuthenticationConstants.Namespaces.LegacyIdentifier.Length); } // Prevent the sign-in operation from completing if the claimed identifier is malformed. else { Logger.LogWarning("The userinfo request was skipped because an invalid identifier was received: {Identifier}.", identifier); throw new InvalidOperationException($"The OpenID claimed identifier '{identifier}' is not valid."); } var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary <string, string> { [SteamAuthenticationConstants.Parameters.Key] = Options.ApplicationKey, [SteamAuthenticationConstants.Parameters.SteamId] = identifier }); var request = new HttpRequestMessage(HttpMethod.Get, address); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(OpenIdAuthenticationConstants.Media.Json)); // Return the authentication ticket as-is if the userinfo request failed. var response = await Options.Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted); if (!response.IsSuccessStatusCode) { Logger.LogWarning("The userinfo request failed because an invalid response was received: the identity provider " + "returned returned a {Status} response with the following payload: {Headers} {Body}.", /* Status: */ response.StatusCode, /* Headers: */ response.Headers.ToString(), /* Body: */ await response.Content.ReadAsStringAsync()); throw new HttpRequestException("An error occurred while retrieving the user profile from Steam."); } using var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync()); // Try to extract the profile name of the authenticated user. var profile = payload.RootElement .GetProperty(SteamAuthenticationConstants.Parameters.Response) .GetProperty(SteamAuthenticationConstants.Parameters.Players) .EnumerateArray() .FirstOrDefault(); if (profile.ValueKind == JsonValueKind.Object && profile.TryGetProperty(SteamAuthenticationConstants.Parameters.Name, out var name)) { identity.AddClaim(new Claim(ClaimTypes.Name, name.GetString(), ClaimValueTypes.String, Options.ClaimsIssuer)); } return(await RunAuthenticatedEventAsync(payload)); async Task <AuthenticationTicket> RunAuthenticatedEventAsync(JsonDocument user = null) { var context = new OpenIdAuthenticatedContext(Context, Scheme, Options, ticket) { UserPayload = user }; if (user != null) { #pragma warning disable CS0618 context.User = JObject.Parse(user.RootElement.ToString()); #pragma warning restore CS0618 } // Copy the attributes to the context object. foreach (var attribute in attributes) { context.Attributes.Add(attribute); } await Events.Authenticated(context); // Note: return the authentication ticket associated // with the notification to allow replacing the ticket. return(context.Ticket); } }