public Task<ValidationResult> ValidateAuthorizeRequestAsync(ValidatedAuthorizeRequest request, Core.Services.IUserService profile) { return Task.FromResult(new ValidationResult { IsError = false }); }
public ConsentModel(ValidatedAuthorizeRequest validatedRequest, NameValueCollection requestParameters) { var requestedScopes = validatedRequest.ValidatedScopes.RequestedScopes; var consentedScopeNames = validatedRequest.ValidatedScopes.GrantedScopes.Select(x => x.Name); var idScopes = from s in requestedScopes where s.IsOpenIdScope select new { selected = consentedScopeNames.Contains(s.Name), s.Name, s.DisplayName, s.Description, s.Emphasize, s.Required }; var appScopes = from s in requestedScopes where !s.IsOpenIdScope select new { selected = consentedScopeNames.Contains(s.Name), s.Name, s.DisplayName, s.Description, s.Emphasize, s.Required }; postUrl = "consent?" + requestParameters.ToQueryString(); client = validatedRequest.Client.ClientName; clientUrl = validatedRequest.Client.ClientUri; clientLogo = validatedRequest.Client.LogoUri; identityScopes = idScopes.ToArray(); applicationScopes = appScopes.ToArray(); allowRememberConsent = validatedRequest.Client.AllowRememberConsent; }
async Task <IHttpActionResult> AuthorizeErrorAsync(ErrorTypes errorType, string error, ValidatedAuthorizeRequest request) { await RaiseFailureEventAsync(error); // show error message to user if (errorType == ErrorTypes.User) { var env = Request.GetOwinEnvironment(); var errorModel = new ErrorViewModel { RequestId = env.GetRequestId(), SiteName = _options.SiteName, SiteUrl = env.GetIdentityServerBaseUrl(), CurrentUser = env.GetCurrentUserDisplayName(), LogoutUrl = env.GetIdentityServerLogoutUrl(), ErrorMessage = LookupErrorMessage(error) }; var errorResult = new ErrorActionResult(_viewService, errorModel); return(errorResult); } // return error to client var response = new AuthorizeResponse { Request = request, IsError = true, Error = error, State = request.State, RedirectUri = request.RedirectUri }; if (request.ResponseMode == Constants.ResponseModes.FormPost) { return(new AuthorizeFormPostResult(response, Request)); } else { return(new AuthorizeRedirectResult(response, _options)); } }
private void AssertErrorReturnsRequestValues(AuthorizeError error, ValidatedAuthorizeRequest request) { error.ResponseMode.Should().Be(request.ResponseMode); error.ErrorUri.Should().Be(request.RedirectUri); error.State.Should().Be(request.State); }
public async Task <ConsentInteractionResponse> ProcessConsentAsync(ValidatedAuthorizeRequest request, UserConsent consent = null) { if (request == null) { throw new ArgumentNullException("request"); } if (request.PromptMode != null && request.PromptMode != Constants.PromptModes.None && request.PromptMode != Constants.PromptModes.Consent) { throw new ArgumentException("Invalid PromptMode"); } var consentRequired = await _consent.RequiresConsentAsync(request.Client, request.Subject, request.RequestedScopes); if (consentRequired && request.PromptMode == Constants.PromptModes.None) { Logger.Info("Prompt=none requested, but consent is required."); return(new ConsentInteractionResponse { Error = new AuthorizeError { ErrorType = ErrorTypes.Client, Error = Constants.AuthorizeErrors.InteractionRequired, ResponseMode = request.ResponseMode, ErrorUri = request.RedirectUri, State = request.State } }); } if (request.PromptMode == Constants.PromptModes.Consent || consentRequired) { var response = new ConsentInteractionResponse(); // did user provide consent if (consent == null) { // user was not yet shown conset screen response.IsConsent = true; } else { request.WasConsentShown = true; // user was shown consent -- did they say yes or no if (consent.WasConsentGranted == false) { // no need to show consent screen again // build access denied error to return to client response.Error = new AuthorizeError { ErrorType = ErrorTypes.Client, Error = Constants.AuthorizeErrors.AccessDenied, ResponseMode = request.ResponseMode, ErrorUri = request.RedirectUri, State = request.State }; } else { // they said yes, set scopes they chose request.ValidatedScopes.SetConsentedScopes(consent.ScopedConsented); if (!request.ValidatedScopes.GrantedScopes.Any()) { // they said yes, but didn't pick any scopes // show consent again and provide error message response.IsConsent = true; response.ConsentError = _localizationService.GetMessage(MessageIds.MustSelectAtLeastOnePermission); } else if (request.Client.AllowRememberConsent) { // remember consent var scopes = Enumerable.Empty <string>(); if (consent.RememberConsent) { // remember what user actually selected scopes = request.ValidatedScopes.GrantedScopes.Select(x => x.Name); } await _consent.UpdateConsentAsync(request.Client, request.Subject, scopes); } } } return(response); } return(new ConsentInteractionResponse()); }
public async Task <Stream> Consent(ConsentViewModel model, ValidatedAuthorizeRequest authorizeRequest) { return(await Render(model, "Consent")); }
public static void RemoveIdP(this ValidatedAuthorizeRequest request) { request.RemovePrefixedAcrValue(Constants.KnownAcrValues.HomeRealm); }
public static void RemovePrompt(this ValidatedAuthorizeRequest request) { request.PromptMode = null; request.Raw.Remove(OidcConstants.AuthorizeRequest.Prompt); }
/// <summary> /// Processes the login logic. /// </summary> /// <param name="request">The request.</param> /// <returns></returns> protected internal virtual async Task <InteractionResponse> ProcessLoginAsync(ValidatedAuthorizeRequest request) { if (request.PromptMode == OidcConstants.PromptModes.Login || request.PromptMode == OidcConstants.PromptModes.SelectAccount) { // remove prompt so when we redirect back in from login page // we won't think we need to force a prompt again request.RemovePrompt(); _logger.LogInformation("Showing login: request contains prompt={0}", request.PromptMode); return(new InteractionResponse { IsLogin = true }); } // unauthenticated user var isAuthenticated = request.Subject.IsAuthenticated(); // user de-activated bool isActive = false; if (isAuthenticated) { var isActiveCtx = new IsActiveContext(request.Subject, request.Client, IdentityServerConstants.ProfileIsActiveCallers.AuthorizeEndpoint); await _profile.IsActiveAsync(isActiveCtx); isActive = isActiveCtx.IsActive; } if (!isAuthenticated || !isActive) { // prompt=none means user must be signed in already if (request.PromptMode == OidcConstants.PromptModes.None) { if (!isAuthenticated) { _logger.LogInformation("Showing error: prompt=none was requested but user is not authenticated"); } else if (!isActive) { _logger.LogInformation("Showing error: prompt=none was requested but user is not active"); } return(new InteractionResponse { Error = OidcConstants.AuthorizeErrors.LoginRequired }); } if (!isAuthenticated) { _logger.LogInformation("Showing login: User is not authenticated"); } else if (!isActive) { _logger.LogInformation("Showing login: User is not active"); } return(new InteractionResponse { IsLogin = true }); } // check current idp var currentIdp = request.Subject.GetIdentityProvider(); // check if idp login hint matches current provider var idp = request.GetIdP(); if (idp.IsPresent()) { if (idp != currentIdp) { _logger.LogInformation("Showing login: Current IdP ({idp}) is not the requested IdP ({idp})", currentIdp, idp); return(new InteractionResponse { IsLogin = true }); } } // check authentication freshness if (request.MaxAge.HasValue) { var authTime = request.Subject.GetAuthenticationTime(); if (IdentityServerDateTime.UtcNow > authTime.AddSeconds(request.MaxAge.Value)) { _logger.LogInformation("Showing login: Requested MaxAge exceeded."); return(new InteractionResponse { IsLogin = true }); } } // check local idp restrictions if (currentIdp == IdentityServerConstants.LocalIdentityProvider && !request.Client.EnableLocalLogin) { _logger.LogInformation("Showing login: User logged in locally, but client does not allow local logins"); return(new InteractionResponse { IsLogin = true }); } // check external idp restrictions if (request.Client.IdentityProviderRestrictions != null && request.Client.IdentityProviderRestrictions.Any()) { if (!request.Client.IdentityProviderRestrictions.Contains(currentIdp)) { _logger.LogInformation("Showing login: User is logged in with idp: {idp}, but idp not in client restriction list.", currentIdp); return(new InteractionResponse { IsLogin = true }); } } return(new InteractionResponse()); }
/// <summary> /// Processes the consent logic. /// </summary> /// <param name="request">The request.</param> /// <param name="consent">The consent.</param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentException">Invalid PromptMode</exception> protected internal virtual async Task <InteractionResponse> ProcessConsentAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null) { if (request == null) { throw new ArgumentNullException(nameof(request)); } if (request.PromptMode != null && request.PromptMode != OidcConstants.PromptModes.None && request.PromptMode != OidcConstants.PromptModes.Consent) { _logger.LogError("Invalid prompt mode: {promptMode}", request.PromptMode); throw new ArgumentException("Invalid PromptMode"); } var consentRequired = await _consent.RequiresConsentAsync(request.Subject, request.Client, request.RequestedScopes); if (consentRequired && request.PromptMode == OidcConstants.PromptModes.None) { _logger.LogInformation("Error: prompt=none requested, but consent is required."); return(new InteractionResponse { Error = OidcConstants.AuthorizeErrors.ConsentRequired }); } if (request.PromptMode == OidcConstants.PromptModes.Consent || consentRequired) { var response = new InteractionResponse(); // did user provide consent if (consent == null) { // user was not yet shown conset screen response.IsConsent = true; _logger.LogInformation("Showing consent: User has not yet consented"); } else { request.WasConsentShown = true; _logger.LogTrace("Consent was shown to user"); // user was shown consent -- did they say yes or no if (consent.Granted == false) { // no need to show consent screen again // build access denied error to return to client response.Error = OidcConstants.AuthorizeErrors.AccessDenied; _logger.LogInformation("Error: User denied consent"); } else { // double check that required scopes are in the list of consented scopes var valid = request.ValidatedScopes.ValidateRequiredScopes(consent.ScopesConsented); if (valid == false) { response.Error = OidcConstants.AuthorizeErrors.AccessDenied; _logger.LogInformation("Error: User denied consent to required scopes"); } else { // they said yes, set scopes they chose request.ValidatedScopes.SetConsentedScopes(consent.ScopesConsented); _logger.LogInformation("User consented to scopes: {scopes}", consent.ScopesConsented); if (request.Client.AllowRememberConsent) { // remember consent var scopes = Enumerable.Empty <string>(); if (consent.RememberConsent) { // remember what user actually selected scopes = request.ValidatedScopes.GrantedResources.ToScopeNames(); _logger.LogDebug("User indicated to remember consent for scopes: {scopes}", scopes); } await _consent.UpdateConsentAsync(request.Subject, request.Client, scopes); } } } } return(response); } return(new InteractionResponse()); }
/// <summary> /// Initializes a new instance of the <see cref="AuthorizeRequestValidationResult"/> class. /// </summary> /// <param name="request">The request.</param> public AuthorizeRequestValidationResult(ValidatedAuthorizeRequest request) { ValidatedRequest = request; IsError = false; }
public async Task <IEndpointResult> CreateAuthorizeResultAsync(ValidatedAuthorizeRequest request) { var response = await _responseGenerator.CreateResponseAsync(request); return(await CreateAuthorizeResultAsync(response)); }
public async Task <IEndpointResult> CreateErrorResultAsync(ErrorTypes errorType, string error, ValidatedAuthorizeRequest request) { if (errorType == ErrorTypes.Client && request == null) { throw new ArgumentNullException(nameof(request), "Request must be passed when error type is Client."); } AuthorizeResponse response = null; if (errorType == ErrorTypes.Client) { response = new AuthorizeResponse { Request = request, IsError = true, Error = error, State = request.State, RedirectUri = request.RedirectUri }; // do some early checks to see if we will end up not generating an error page if (error == OidcConstants.AuthorizeErrors.AccessDenied) { return(await CreateAuthorizeResultAsync(response)); } if (request.PromptMode == OidcConstants.PromptModes.None && request.Client.AllowPromptNone == true && (error == OidcConstants.AuthorizeErrors.LoginRequired || error == OidcConstants.AuthorizeErrors.ConsentRequired || error == OidcConstants.AuthorizeErrors.InteractionRequired) ) { // todo: verify these are the right conditions to allow // redirecting back to client // https://tools.ietf.org/html/draft-bradley-oauth-open-redirector-00 return(await CreateAuthorizeResultAsync(response)); } else { //_logger.LogWarning("Rendering error page due to prompt=none, client does not allow prompt mode none, response is query, and "); } } // we now know we must show error page var msg = _localizationService.GetMessage(error); if (msg.IsMissing()) { msg = error; } var errorModel = new ErrorMessage { RequestId = _context.GetRequestId(), ErrorCode = error, ErrorDescription = msg }; if (errorType == ErrorTypes.Client) { // if this is a client error, we need to build up the // response back to the client, and provide it in the // error view model so the UI can build the link/form errorModel.ReturnInfo = new ClientReturnInfo { ClientId = request.ClientId, }; if (request.ResponseMode == OidcConstants.ResponseModes.Query || request.ResponseMode == OidcConstants.ResponseModes.Fragment) { errorModel.ReturnInfo.Uri = request.RedirectUri = AuthorizeRedirectResult.BuildUri(response); } else if (request.ResponseMode == OidcConstants.ResponseModes.FormPost) { errorModel.ReturnInfo.Uri = request.RedirectUri; errorModel.ReturnInfo.PostBody = AuthorizeFormPostResult.BuildFormBody(response); } else { _logger.LogError("Unsupported response mode."); throw new InvalidOperationException("Unsupported response mode"); } } var message = new Message <ErrorMessage>(errorModel); await _errorMessageStore.WriteAsync(message); return(new ErrorPageResult(message.Id)); }
internal async Task <InteractionResponse> ProcessLoginAsync(ValidatedAuthorizeRequest request) { if (request.PromptMode == OidcConstants.PromptModes.Login) { // remove prompt so when we redirect back in from login page // we won't think we need to force a prompt again request.Raw.Remove(OidcConstants.AuthorizeRequest.Prompt); _logger.LogInformation("Redirecting to login page because of prompt=login"); return(new InteractionResponse() { IsLogin = true }); } // unauthenticated user var isAuthenticated = request.Subject.Identity.IsAuthenticated; // user de-activated bool isActive = false; if (isAuthenticated) { var isActiveCtx = new IsActiveContext(request.Subject, request.Client); await _profile.IsActiveAsync(isActiveCtx); isActive = isActiveCtx.IsActive; } if (!isAuthenticated || !isActive) { if (!isAuthenticated) { _logger.LogInformation("User is not authenticated."); } else if (!isActive) { _logger.LogInformation("User is not active."); } // prompt=none means user must be signed in already if (request.PromptMode == OidcConstants.PromptModes.None) { _logger.LogInformation("prompt=none was requested but user is not authenticated/active."); return(new InteractionResponse { Error = new AuthorizeError { ErrorType = ErrorTypes.Client, Error = OidcConstants.AuthorizeErrors.LoginRequired, ResponseMode = request.ResponseMode, ErrorUri = request.RedirectUri, State = request.State } }); } return(new InteractionResponse() { IsLogin = true }); } // check current idp var currentIdp = request.Subject.GetIdentityProvider(); // check if idp login hint matches current provider var idp = request.GetIdP(); if (idp.IsPresent()) { if (idp != currentIdp) { _logger.LogInformation("Current IdP is not the requested IdP. Redirecting to login"); _logger.LogInformation("Current: {0} -- Requested: {1}", currentIdp, idp); return(new InteractionResponse() { IsLogin = true }); } } // check authentication freshness if (request.MaxAge.HasValue) { var authTime = request.Subject.GetAuthenticationTime(); if (DateTimeOffsetHelper.UtcNow > authTime.AddSeconds(request.MaxAge.Value)) { _logger.LogInformation("Requested MaxAge exceeded."); return(new InteractionResponse() { IsLogin = true }); } } // check idp restrictions if (request.Client.IdentityProviderRestrictions != null && request.Client.IdentityProviderRestrictions.Any()) { if (!request.Client.IdentityProviderRestrictions.Contains(currentIdp)) { _logger.LogWarning("User is logged in with idp: {0}, but idp not in client restriction list.", currentIdp); return(new InteractionResponse() { IsLogin = true }); } } // check if idp is local and local logins are not allowed if (currentIdp == Constants.BuiltInIdentityProvider) { if (_options.AuthenticationOptions.EnableLocalLogin == false || request.Client.EnableLocalLogin == false) { _logger.LogWarning("User is logged in with local idp, but local logins not enabled."); return(new InteractionResponse() { IsLogin = true }); } } return(new InteractionResponse()); }
internal async Task <InteractionResponse> ProcessConsentAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null) { if (request == null) { throw new ArgumentNullException("request"); } if (request.PromptMode != null && request.PromptMode != OidcConstants.PromptModes.None && request.PromptMode != OidcConstants.PromptModes.Consent) { throw new ArgumentException("Invalid PromptMode"); } var consentRequired = await _consent.RequiresConsentAsync(request.Client, request.Subject, request.RequestedScopes); if (consentRequired && request.PromptMode == OidcConstants.PromptModes.None) { _logger.LogInformation("Prompt=none requested, but consent is required."); return(new InteractionResponse { Error = new AuthorizeError { ErrorType = ErrorTypes.Client, Error = OidcConstants.AuthorizeErrors.ConsentRequired, ResponseMode = request.ResponseMode, ErrorUri = request.RedirectUri, State = request.State } }); } if (request.PromptMode == OidcConstants.PromptModes.Consent || consentRequired) { var response = new InteractionResponse(); // did user provide consent if (consent == null) { // user was not yet shown conset screen response.IsConsent = true; } else { request.WasConsentShown = true; // user was shown consent -- did they say yes or no if (consent.Granted == false) { // no need to show consent screen again // build access denied error to return to client response.Error = new AuthorizeError { ErrorType = ErrorTypes.Client, Error = OidcConstants.AuthorizeErrors.AccessDenied, ResponseMode = request.ResponseMode, ErrorUri = request.RedirectUri, State = request.State }; } else { // double check that required scopes are in the list of consented scopes var valid = request.ValidatedScopes.ValidateRequiredScopes(consent.ScopesConsented); if (valid == false) { response.Error = new AuthorizeError { ErrorType = ErrorTypes.Client, Error = OidcConstants.AuthorizeErrors.AccessDenied, ResponseMode = request.ResponseMode, ErrorUri = request.RedirectUri, State = request.State }; } else { // they said yes, set scopes they chose request.ValidatedScopes.SetConsentedScopes(consent.ScopesConsented); if (request.Client.AllowRememberConsent) { // remember consent var scopes = Enumerable.Empty <string>(); if (consent.RememberConsent) { // remember what user actually selected scopes = request.ValidatedScopes.GrantedScopes.Select(x => x.Name); } await _consent.UpdateConsentAsync(request.Client, request.Subject, scopes); } } } } return(response); } return(new InteractionResponse()); }
private Task RaiseFailureEventAsync(ValidatedAuthorizeRequest request, string error, string errorDescription) { return(_events.RaiseAsync(new TokenIssuedFailureEvent(request, error, errorDescription))); }
/// <summary> /// Creates the response for a hybrid flow request /// </summary> /// <param name="request"></param> /// <returns></returns> protected virtual async Task <AuthorizeResponse> CreateHybridFlowResponseAsync(ValidatedAuthorizeRequest request) { Logger.LogDebug("Creating Hybrid Flow response."); var code = await CreateCodeAsync(request); var response = await CreateImplicitFlowResponseAsync(request, code); response.Code = code; return(response); }
public async Task <IEndpointResult> ProcessAsync(HttpContext context) { string key = null; try { var request = new ValidatedAuthorizeRequest(); _logger.LogInformation("Process AuthorizeEndpoint Start.._signinManager.SignOutAsync() "); await _signinManager.SignOutAsync(); /* * https://localhost:44305/connect/authorize? * client_id=mvc * &redirect_uri=https%3A%2F%2Fp7core.127.0.0.1.xip.io%3A44311%2Fsignin-oidc * &response_type=id_token * &scope=openid%20profile * &response_mode=form_post * &nonce=636973229335838266.ZWJhM2U4M2YtYWNiYi00YjZkLTkwMWYtNjRmMjM3MWRiYTk5OWNkNDIzMWUtZmY4OS00YWE0LTk4MGUtMTdiMjYxNmNmZjRk&state=CfDJ8KOz5LEySMhBtqpccMk4UVhA1PvGQQvpqQBUyR-97TDZvaPuNquTLJIUxKMYzF-Ov_HHCnnmcTForzd5RJ4jmLONvcZLY3XCHnrhh9Sc2oR2Lv2HACvPVBMy2oYmmPBtNIoXroQ9WePE_KtPyFw8ntRsHIYMmT5a0fLKGeJcwK3ewoiRHxjKpOr9hXZau9f7CVVqMvtWC2ngWrFsEeh8S0YtRZQFT-7XyjE9dNiyKp_Z-4iBUbbqzVnT4GmEmErZXUjmBhmVsMLz5h9y_F3usRT3lg7LxUNamnJuROnYIqmJzf0fYVJq1mcB5hcUipo2SNcILG3xkUikc84VznSGvD7V_qFjOHVPtOEX02JH9M4ymb3iZtZSE9dDr2RkwTU7StoKgM-x195bBULpwms8weJO-kx5I6UrY_lmWl0SFqYN * &x-client-SKU=ID_NETSTANDARD2_0 * &x-client-ver=5.4.0.0 * */ SimpleNameValueCollection values; if (HttpMethods.IsGet(context.Request.Method)) { values = context.Request.Query.AsNameValueCollection(); } else if (HttpMethods.IsPost(context.Request.Method)) { if (!context.Request.HasFormContentType) { return(new OIDCPipeline.Core.Endpoints.Results.StatusCodeResult((int)HttpStatusCode.UnsupportedMediaType)); } values = context.Request.Form.AsNameValueCollection(); } else { return(new OIDCPipeline.Core.Endpoints.Results.StatusCodeResult((int)HttpStatusCode.MethodNotAllowed)); } request.Raw = values; var result = await _authorizeRequestValidator.ValidateAsync(request); _logger.LogInformation($"Method:{context.Request.Method} ValidateAsync Error:{result.IsError}"); string redirectUrl = null; if (!result.IsError) { if (string.IsNullOrWhiteSpace(request.Nonce)) { request.Nonce = GenerateNonce(); values["OidcConstants.AuthorizeRequest.Nonce"] = request.Nonce; } var downstreamAuthorizationRequest = values.ToDownstreamAuthorizationRequest(); key = _oidcPipeLineKey.GetOIDCPipeLineKey(); if (!string.IsNullOrWhiteSpace(key)) { _logger.LogInformation($"DeleteStoredCacheAsync previouse if it exists"); await _oidcPipelineStore.DeleteStoredCacheAsync(key); } // Initially was using the NONCE as the key, but we can't trust that clients will not hardcode a nonce // The key has to be generated on our side and subsequently stored as a cookie. key = Guid.NewGuid().ToString("N"); // context.SetOIDCPipeLineKey(key); _logger.LogInformation($"StoreOriginalIdTokenRequestAsync clientid:{downstreamAuthorizationRequest.client_id}"); await _oidcPipelineStore.StoreOriginalAuthorizeRequestAsync(key, result.ValidatedAuthorizeRequest); redirectUrl = $"{context.Request.Scheme}://{context.Request.Host}{_options.PostAuthorizeHookRedirectUrl}"; } else { redirectUrl = $"{context.Request.Scheme}://{context.Request.Host}{_options.PostAuthorizeHookErrorRedirectUrl}"; } _logger.LogInformation($"redirecting to:{redirectUrl}"); return(new Results.OriginalAuthorizeResult(_oidcPipeLineKey, redirectUrl, key)); } catch (Exception ex) { string redirectUrl = $"{context.Request.Scheme}://{context.Request.Host}{_options.PostAuthorizeHookErrorRedirectUrl}"; return(new Results.OriginalAuthorizeResult(_oidcPipeLineKey, redirectUrl, key)); } }
public static string GetIdP(this ValidatedAuthorizeRequest request) { return(request.GetPrefixedAcrValue(Constants.KnownAcrValues.HomeRealm)); }
private void AssertErrorReturnsRequestValues(AuthorizeError error, ValidatedAuthorizeRequest request) { Assert.AreEqual(request.ResponseMode, error.ResponseMode); Assert.AreEqual(request.RedirectUri, error.ErrorUri); Assert.AreEqual(request.State, error.State); }
public static string GetTenant(this ValidatedAuthorizeRequest request) { return(request.GetPrefixedAcrValue(Constants.KnownAcrValues.Tenant)); }
public static string ToOptimizedQueryString(this ValidatedAuthorizeRequest request) { return(request.ToOptimizedRawValues().ToQueryString()); }
public async Task <AuthorizeResponse> CreateImplicitFlowResponseAsync(ValidatedAuthorizeRequest request, string authorizationCode = null) { Logger.Info("Creating Implicit Flow response."); string accessTokenValue = null; int accessTokenLifetime = 0; var responseTypes = request.ResponseType.FromSpaceSeparatedString(); if (responseTypes.Contains(Constants.ResponseTypes.Token)) { var tokenRequest = new TokenCreationRequest { Subject = request.Subject, Client = request.Client, Scopes = request.ValidatedScopes.GrantedScopes, CreateAnonymousToken = request.CanCreateAnonymousToken(), ValidatedRequest = request }; var accessToken = await _tokenService.CreateAccessTokenAsync(tokenRequest); accessTokenLifetime = accessToken.Lifetime; accessTokenValue = await _tokenService.CreateSecurityTokenAsync(accessToken); } string jwt = null; if (responseTypes.Contains(Constants.ResponseTypes.IdToken)) { var tokenRequest = new TokenCreationRequest { ValidatedRequest = request, Subject = request.Subject, Client = request.Client, Scopes = request.ValidatedScopes.GrantedScopes, CreateAnonymousToken = request.CanCreateAnonymousToken(), Nonce = request.Raw.Get(Constants.AuthorizeRequest.Nonce), IncludeAllIdentityClaims = !request.AccessTokenRequested, AccessTokenToHash = accessTokenValue, AuthorizationCodeToHash = authorizationCode }; var idToken = await _tokenService.CreateIdentityTokenAsync(tokenRequest); jwt = await _tokenService.CreateSecurityTokenAsync(idToken); } var response = new AuthorizeResponse { Request = request, RedirectUri = request.RedirectUri, AccessToken = accessTokenValue, AccessTokenLifetime = accessTokenLifetime, IdentityToken = jwt, State = request.State, Scope = request.ValidatedScopes.GrantedScopes.ToSpaceSeparatedString(), }; if (request.IsOpenIdRequest) { response.SessionState = GenerateSessionStateValue(request); } return(response); }
public static IDictionary <string, string[]> ToOptimizedFullDictionary(this ValidatedAuthorizeRequest request) { return(request.ToOptimizedRawValues().ToFullDictionary()); }
public async Task <LoginInteractionResponse> ProcessLoginAsync(ValidatedAuthorizeRequest request, ClaimsPrincipal user) { // let the login page know the client requesting authorization _signIn.ClientId = request.ClientId; // pass through display mode to signin service if (request.DisplayMode.IsPresent()) { _signIn.DisplayMode = request.DisplayMode; } // pass through ui locales to signin service if (request.UiLocales.IsPresent()) { _signIn.UiLocales = request.UiLocales; } // pass through login_hint if (request.LoginHint.IsPresent()) { _signIn.LoginHint = request.LoginHint; } // process acr values var acrValues = request.AuthenticationContextReferenceClasses.Distinct().ToList(); // look for well-known acr value -- idp var idp = acrValues.FirstOrDefault(x => x.StartsWith(Constants.KnownAcrValues.HomeRealm)); if (idp.IsPresent()) { _signIn.IdP = idp.Substring(Constants.KnownAcrValues.HomeRealm.Length); acrValues.Remove(idp); } // look for well-known acr value -- tenant var tenant = acrValues.FirstOrDefault(x => x.StartsWith(Constants.KnownAcrValues.Tenant)); if (tenant.IsPresent()) { _signIn.Tenant = tenant.Substring(Constants.KnownAcrValues.Tenant.Length); acrValues.Remove(tenant); } // pass through any remaining acr values if (acrValues.Any()) { _signIn.AcrValues = acrValues; } // pass through the prompt mode if (request.PromptMode.IsPresent()) { _signIn.Prompt = request.PromptMode; } if (request.PromptMode == Constants.PromptModes.Login) { // remove prompt so when we redirect back in from login page // we won't think we need to force a prompt again request.Raw.Remove(Constants.AuthorizeRequest.Prompt); Logger.Info("Redirecting to login page because of prompt=login"); return(new LoginInteractionResponse { SignInMessage = _signIn }); } // unauthenticated user var isAuthenticated = user.Identity.IsAuthenticated; if (!isAuthenticated) { Logger.Info("User is not authenticated. Redirecting to login."); } // user de-activated bool isActive = false; if (isAuthenticated) { var isActiveCtx = new IsActiveContext(user, request.Client); await _users.IsActiveAsync(isActiveCtx); isActive = isActiveCtx.IsActive; if (!isActive) { Logger.Info("User is not active. Redirecting to login."); } } if (!isAuthenticated || !isActive) { // prompt=none means user must be signed in already if (request.PromptMode == Constants.PromptModes.None) { Logger.Info("prompt=none was requested. But user is not authenticated."); return(new LoginInteractionResponse { Error = new AuthorizeError { ErrorType = ErrorTypes.Client, Error = Constants.AuthorizeErrors.LoginRequired, ResponseMode = request.ResponseMode, ErrorUri = request.RedirectUri, State = request.State } }); } return(new LoginInteractionResponse { SignInMessage = _signIn }); } // check current idp var currentIdp = user.GetIdentityProvider(); // check if idp login hint matches current provider if (_signIn.IdP.IsPresent()) { if (_signIn.IdP != currentIdp) { Logger.Info("Current IdP is not the requested IdP. Redirecting to login"); Logger.InfoFormat("Current: {0} -- Requested: {1}", currentIdp, _signIn.IdP); return(new LoginInteractionResponse { SignInMessage = _signIn }); } } // check authentication freshness if (request.MaxAge.HasValue) { var authTime = user.GetAuthenticationTime(); if (DateTimeOffsetHelper.UtcNow > authTime.AddSeconds(request.MaxAge.Value)) { Logger.Info("Requested MaxAge exceeded. Redirecting to login"); return(new LoginInteractionResponse { SignInMessage = _signIn }); } } return(new LoginInteractionResponse()); }
/// <summary> /// Processes the login logic. /// </summary> /// <param name="request">The request.</param> /// <returns></returns> protected internal virtual async Task <InteractionResponse> ProcessLoginAsync(ValidatedAuthorizeRequest request) { if (request.PromptModes.Contains(OidcConstants.PromptModes.Login) || request.PromptModes.Contains(OidcConstants.PromptModes.SelectAccount)) { Logger.LogInformation("Showing login: request contains prompt={0}", request.PromptModes.ToSpaceSeparatedString()); // remove prompt so when we redirect back in from login page // we won't think we need to force a prompt again request.RemovePrompt(); return(new InteractionResponse { IsLogin = true }); } // unauthenticated user var isAuthenticated = request.Subject.IsAuthenticated(); // user de-activated bool isActive = false; if (isAuthenticated) { var isActiveCtx = new IsActiveContext(request.Subject, request.Client, IdentityServerConstants.ProfileIsActiveCallers.AuthorizeEndpoint); await Profile.IsActiveAsync(isActiveCtx); isActive = isActiveCtx.IsActive; } if (!isAuthenticated || !isActive) { if (!isAuthenticated) { Logger.LogInformation("Showing login: User is not authenticated"); } else if (!isActive) { Logger.LogInformation("Showing login: User is not active"); } return(new InteractionResponse { IsLogin = true }); } // check current idp var currentIdp = request.Subject.GetIdentityProvider(); // check if idp login hint matches current provider var idp = request.GetIdP(); if (idp.IsNullOrEmpty()) { if (idp != currentIdp) { Logger.LogInformation("Showing login: Current IdP ({currentIdp}) is not the requested IdP ({idp})", currentIdp, idp); return(new InteractionResponse { IsLogin = true }); } } // check authentication freshness if (request.MaxAge.HasValue) { var authTime = request.Subject.GetAuthenticationTime(); if (Clock.UtcNow > authTime.AddSeconds(request.MaxAge.Value)) { Logger.LogInformation("Showing login: Requested MaxAge exceeded."); return(new InteractionResponse { IsLogin = true }); } } // check local idp restrictions if (currentIdp == IdentityServerConstants.LocalIdentityProvider) { if (!request.Client.EnableLocalLogin) { Logger.LogInformation("Showing login: User logged in locally, but client does not allow local logins"); return(new InteractionResponse { IsLogin = true }); } } // check external idp restrictions if user not using local idp else if (request.Client.IdentityProviderRestrictions != null && request.Client.IdentityProviderRestrictions.Any() && !request.Client.IdentityProviderRestrictions.Contains(currentIdp)) { Logger.LogInformation("Showing login: User is logged in with idp: {idp}, but idp not in client restriction list.", currentIdp); return(new InteractionResponse { IsLogin = true }); } // check client's user SSO timeout if (request.Client.UserSsoLifetime.HasValue) { var authTimeEpoch = request.Subject.GetAuthenticationTimeEpoch(); var nowEpoch = Clock.UtcNow.ToUnixTimeSeconds(); var diff = nowEpoch - authTimeEpoch; if (diff > request.Client.UserSsoLifetime.Value) { Logger.LogInformation("Showing login: User's auth session duration: {sessionDuration} exceeds client's user SSO lifetime: {userSsoLifetime}.", diff, request.Client.UserSsoLifetime); return(new InteractionResponse { IsLogin = true }); } } return(new InteractionResponse()); }
public static bool CanCreateAnonymousToken(this ValidatedAuthorizeRequest validatedRequest) { return(validatedRequest.AnonymousTokenRequested && validatedRequest.Subject.IsAnonymousAuthenticationMethod()); }
/// <summary> /// Processes the consent logic. /// </summary> /// <param name="request">The request.</param> /// <param name="consent">The consent.</param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentException">Invalid PromptMode</exception> protected internal virtual async Task <InteractionResponse> ProcessConsentAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null) { if (request == null) { throw new ArgumentNullException(nameof(request)); } if (request.PromptModes.Any() && !request.PromptModes.Contains(OidcConstants.PromptModes.None) && !request.PromptModes.Contains(OidcConstants.PromptModes.Consent)) { Logger.LogError("Invalid prompt mode: {promptMode}", request.PromptModes.ToSpaceSeparatedString()); throw new ArgumentException("Invalid PromptMode"); } var consentRequired = await Consent.RequiresConsentAsync(request.Subject, request.Client, request.ValidatedResources.ParsedScopes); if (consentRequired && request.PromptModes.Contains(OidcConstants.PromptModes.None)) { Logger.LogInformation("Error: prompt=none requested, but consent is required."); return(new InteractionResponse { Error = OidcConstants.AuthorizeErrors.ConsentRequired }); } if (request.PromptModes.Contains(OidcConstants.PromptModes.Consent) || consentRequired) { var response = new InteractionResponse(); // did user provide consent if (consent == null) { // user was not yet shown conset screen response.IsConsent = true; Logger.LogInformation("Showing consent: User has not yet consented"); } else { request.WasConsentShown = true; Logger.LogTrace("Consent was shown to user"); // user was shown consent -- did they say yes or no if (consent.Granted == false) { // no need to show consent screen again // build error to return to client Logger.LogInformation("Error: User consent result: {error}", consent.Error); var error = consent.Error switch { AuthorizationError.AccountSelectionRequired => OidcConstants.AuthorizeErrors.AccountSelectionRequired, AuthorizationError.ConsentRequired => OidcConstants.AuthorizeErrors.ConsentRequired, AuthorizationError.InteractionRequired => OidcConstants.AuthorizeErrors.InteractionRequired, AuthorizationError.LoginRequired => OidcConstants.AuthorizeErrors.LoginRequired, _ => OidcConstants.AuthorizeErrors.AccessDenied }; response.Error = error; response.ErrorDescription = consent.ErrorDescription; } else { // double check that required scopes are in the list of consented scopes var requiredScopes = request.ValidatedResources.GetRequiredScopeValues(); var valid = requiredScopes.All(x => consent.ScopesValuesConsented.Contains(x)); if (valid == false) { response.Error = OidcConstants.AuthorizeErrors.AccessDenied; Logger.LogInformation("Error: User denied consent to required scopes"); } else { // they said yes, set scopes they chose request.Description = consent.Description; request.ValidatedResources = request.ValidatedResources.Filter(consent.ScopesValuesConsented); Logger.LogInformation("User consented to scopes: {scopes}", consent.ScopesValuesConsented); if (request.Client.AllowRememberConsent) { // remember consent var parsedScopes = Enumerable.Empty <ParsedScopeValue>(); if (consent.RememberConsent) { // remember what user actually selected parsedScopes = request.ValidatedResources.ParsedScopes; Logger.LogDebug("User indicated to remember consent for scopes: {scopes}", request.ValidatedResources.RawScopeValues); } await Consent.UpdateConsentAsync(request.Subject, request.Client, parsedScopes); } } } } return(response); } return(new InteractionResponse()); }
public async Task <AuthorizeResponse> CreateImplicitFlowResponseAsync(ValidatedAuthorizeRequest request, string authorizationCode = null) { _logger.LogDebug("Creating Implicit Flow response."); string accessTokenValue = null; int accessTokenLifetime = 0; var responseTypes = request.ResponseType.FromSpaceSeparatedString(); if (responseTypes.Contains(OidcConstants.ResponseTypes.Token)) { var tokenRequest = new TokenCreationRequest { Subject = request.Subject, Client = request.Client, Resources = request.ValidatedScopes.GrantedResources, ValidatedRequest = request }; var accessToken = await _tokenService.CreateAccessTokenAsync(tokenRequest); accessTokenLifetime = accessToken.Lifetime; accessTokenValue = await _tokenService.CreateSecurityTokenAsync(accessToken); } string jwt = null; if (responseTypes.Contains(OidcConstants.ResponseTypes.IdToken)) { var tokenRequest = new TokenCreationRequest { ValidatedRequest = request, Subject = request.Subject, Client = request.Client, Resources = request.ValidatedScopes.GrantedResources, Nonce = request.Raw.Get(OidcConstants.AuthorizeRequest.Nonce), // if no access token is requested, then we need to include all the claims in the id token IncludeAllIdentityClaims = !request.AccessTokenRequested, AccessTokenToHash = accessTokenValue, AuthorizationCodeToHash = authorizationCode }; var idToken = await _tokenService.CreateIdentityTokenAsync(tokenRequest); jwt = await _tokenService.CreateSecurityTokenAsync(idToken); } var response = new AuthorizeResponse { Request = request, AccessToken = accessTokenValue, AccessTokenLifetime = accessTokenLifetime, IdentityToken = jwt, SessionState = request.GenerateSessionStateValue() }; return(response); }
public async Task <LoginInteractionResponse> ProcessLoginAsync(ValidatedAuthorizeRequest request, ClaimsPrincipal user) { // let the login page know the client requesting authorization _signIn.ClientId = request.ClientId; // pass through display mode to signin service if (request.DisplayMode.IsPresent()) { _signIn.DisplayMode = request.DisplayMode; } // pass through ui locales to signin service if (request.UiLocales.IsPresent()) { _signIn.UiLocales = request.UiLocales; } // check login_hint - we only support idp: right now if (request.LoginHint.IsPresent()) { if (request.LoginHint.StartsWith(Constants.LoginHints.HomeRealm)) { _signIn.IdP = request.LoginHint.Substring(Constants.LoginHints.HomeRealm.Length); } if (request.LoginHint.StartsWith(Constants.LoginHints.Tenant)) { _signIn.Tenant = request.LoginHint.Substring(Constants.LoginHints.Tenant.Length); } } // pass through acr values if (request.AuthenticationContextReferenceClasses.Any()) { _signIn.AcrValues = request.AuthenticationContextReferenceClasses; } if (request.PromptMode == Constants.PromptModes.Login) { // remove prompt so when we redirect back in from login page // we won't think we need to force a prompt again request.Raw.Remove(Constants.AuthorizeRequest.Prompt); return(new LoginInteractionResponse { SignInMessage = _signIn }); } // unauthenticated user var isAuthenticated = user.Identity.IsAuthenticated; if (!isAuthenticated) { Logger.Info("User is not authenticated. Redirecting to login."); } // user de-activated bool isActive = false; if (isAuthenticated) { isActive = await _users.IsActiveAsync(user); if (!isActive) { Logger.Info("User is not active. Redirecting to login."); } } if (!isAuthenticated || !isActive) { // prompt=none means user must be signed in already if (request.PromptMode == Constants.PromptModes.None) { return(new LoginInteractionResponse { Error = new AuthorizeError { ErrorType = ErrorTypes.Client, Error = Constants.AuthorizeErrors.LoginRequired, ResponseMode = request.ResponseMode, ErrorUri = request.RedirectUri, State = request.State } }); } return(new LoginInteractionResponse { SignInMessage = _signIn }); } // check current idp var currentIdp = user.GetIdentityProvider(); // check if idp login hint matches current provider if (_signIn.IdP.IsPresent()) { if (_signIn.IdP != currentIdp) { return(new LoginInteractionResponse { SignInMessage = _signIn }); } } // check authentication freshness if (request.MaxAge.HasValue) { var authTime = user.GetAuthenticationTime(); if (DateTimeOffsetHelper.UtcNow > authTime.AddSeconds(request.MaxAge.Value)) { return(new LoginInteractionResponse { SignInMessage = _signIn }); } } return(new LoginInteractionResponse()); }
/// <summary> /// Initializes a new instance of the <see cref="ConsentPageResult"/> class. /// </summary> /// <param name="request">The request.</param> /// <exception cref="System.ArgumentNullException">request</exception> public ConsentPageResult(ValidatedAuthorizeRequest request) { _request = request ?? throw new ArgumentNullException(nameof(request)); }
private void LogRequest(ValidatedAuthorizeRequest request) { var details = new AuthorizeRequestValidationLog(request, _options.Logging.AuthorizeRequestSensitiveValuesFilter); Logger.LogDebug(nameof(ValidatedAuthorizeRequest) + Environment.NewLine + "{@validationDetails}", details); }