public async Task <ActionResult> ProcessRedirection( AuthorizationParameter authorizationParameter, string code, string subject, List <Claim> claims, string issuerName) { if (authorizationParameter == null) { throw new ArgumentNullException(nameof(authorizationParameter)); } var client = await _clientRepository.GetClientByIdAsync(authorizationParameter.ClientId); if (client == null) { throw new InvalidOperationException(string.Format(ErrorDescriptions.TheClientIdDoesntExist, authorizationParameter.ClientId)); } // Redirect to the consent page if the prompt parameter contains "consent" ActionResult result; var prompts = _parameterParserHelper.ParsePrompts(authorizationParameter.Prompt); if (prompts != null && prompts.Contains(PromptParameter.consent)) { result = _actionResultFactory.CreateAnEmptyActionResultWithRedirection(); result.RedirectInstruction.Action = IdentityServerEndPoints.ConsentIndex; result.RedirectInstruction.AddParameter("code", code); return(result); } var assignedConsent = await _consentHelper.GetConfirmedConsentsAsync(subject, authorizationParameter); // If there's already one consent then redirect to the callback if (assignedConsent != null) { result = _actionResultFactory.CreateAnEmptyActionResultWithRedirectionToCallBackUrl(); var claimsIdentity = new ClaimsIdentity(claims, "simpleIdentityServer"); var claimsPrincipal = new ClaimsPrincipal(claimsIdentity); await _generateAuthorizationResponse.ExecuteAsync(result, authorizationParameter, claimsPrincipal, client, issuerName); var responseMode = authorizationParameter.ResponseMode; if (responseMode == ResponseMode.None) { var responseTypes = _parameterParserHelper.ParseResponseTypes(authorizationParameter.ResponseType); var authorizationFlow = GetAuthorizationFlow(responseTypes, authorizationParameter.State); responseMode = GetResponseMode(authorizationFlow); } result.RedirectInstruction.ResponseMode = responseMode; return(result); } // If there's no consent & there's no consent prompt then redirect to the consent screen. result = _actionResultFactory.CreateAnEmptyActionResultWithRedirection(); result.RedirectInstruction.Action = IdentityServerEndPoints.ConsentIndex; result.RedirectInstruction.AddParameter("code", code); return(result); }
/// <summary> /// Validate the prompt parameter. /// </summary> /// <param name="prompt"></param> /// <param name="state"></param> private void ValidatePromptParameter( string prompt, string state) { if (string.IsNullOrWhiteSpace(prompt)) { return; } var promptNames = Enum.GetNames(typeof(PromptParameter)); var atLeastOnePromptIsNotSupported = prompt.Split(' ') .Any(r => !string.IsNullOrWhiteSpace(r) && !promptNames.Contains(r)); if (atLeastOnePromptIsNotSupported) { throw new IdentityServerExceptionWithState( ErrorCodes.InvalidRequestCode, ErrorDescriptions.AtLeastOnePromptIsNotSupported, state); } var prompts = _parameterParserHelper.ParsePrompts(prompt); if (prompts.Contains(PromptParameter.none) && (prompts.Contains(PromptParameter.login) || prompts.Contains(PromptParameter.consent) || prompts.Contains(PromptParameter.select_account))) { throw new IdentityServerExceptionWithState( ErrorCodes.InvalidRequestCode, ErrorDescriptions.PromptParameterShouldHaveOnlyNoneValue, state); } }
/// <summary> /// Returns an action result to the controller's action. /// 1). Redirect to the consent screen if the user is authenticated AND the request doesn't contain a login prompt. /// 2). Do nothing /// </summary> /// <param name="authorizationParameter">The parameter</param> /// <param name="resourceOwnerPrincipal">Resource owner principal</param> /// <param name="code">Encrypted parameter</param> /// <returns>Action result to the controller's action</returns> public async Task <ActionResult> Execute( AuthorizationParameter authorizationParameter, ClaimsPrincipal resourceOwnerPrincipal, string code) { if (authorizationParameter == null) { throw new ArgumentNullException("authorizationParameter"); } var resourceOwnerIsAuthenticated = resourceOwnerPrincipal.IsAuthenticated(); var promptParameters = _parameterParserHelper.ParsePrompts(authorizationParameter.Prompt); // 1). if (resourceOwnerIsAuthenticated && promptParameters != null && !promptParameters.Contains(PromptParameter.login)) { var subject = resourceOwnerPrincipal.GetSubject(); var claims = resourceOwnerPrincipal.Claims.ToList(); return(await _authenticateHelper.ProcessRedirection(authorizationParameter, code, subject, claims)); } // 2). return(_actionResultFactory.CreateAnEmptyActionResultWithNoEffect()); }
public async Task <ActionResult> ProcessAsync(AuthorizationParameter authorizationParameter, ClaimsPrincipal claimsPrincipal, Core.Common.Models.Client client, string issuerName) { if (authorizationParameter == null) { throw new ArgumentNullException(nameof(authorizationParameter)); } if (client == null) { throw new ArgumentNullException(nameof(client)); } var endUserIsAuthenticated = IsAuthenticated(claimsPrincipal); Consent confirmedConsent = null; if (endUserIsAuthenticated) { confirmedConsent = await GetResourceOwnerConsent(claimsPrincipal, authorizationParameter); } var serializedAuthorizationParameter = authorizationParameter.SerializeWithJavascript(); _oauthEventSource.StartProcessingAuthorizationRequest(serializedAuthorizationParameter); ActionResult result = null; var prompts = _parameterParserHelper.ParsePrompts(authorizationParameter.Prompt); if (prompts == null || !prompts.Any()) { prompts = new List <PromptParameter>(); if (!endUserIsAuthenticated) { prompts.Add(PromptParameter.login); } else { if (confirmedConsent == null) { prompts.Add(PromptParameter.consent); } else { prompts.Add(PromptParameter.none); } } } var redirectionUrls = _clientValidator.GetRedirectionUrls(client, authorizationParameter.RedirectUrl); if (!redirectionUrls.Any()) { throw new IdentityServerExceptionWithState( ErrorCodes.InvalidRequestCode, string.Format(ErrorDescriptions.RedirectUrlIsNotValid, authorizationParameter.RedirectUrl), authorizationParameter.State); } var scopeValidationResult = _scopeValidator.Check(authorizationParameter.Scope, client); if (!scopeValidationResult.IsValid) { throw new IdentityServerExceptionWithState( ErrorCodes.InvalidScope, scopeValidationResult.ErrorMessage, authorizationParameter.State); } if (!scopeValidationResult.Scopes.Contains(Constants.StandardScopes.OpenId.Name)) { throw new IdentityServerExceptionWithState( ErrorCodes.InvalidScope, string.Format(ErrorDescriptions.TheScopesNeedToBeSpecified, Constants.StandardScopes.OpenId.Name), authorizationParameter.State); } var responseTypes = _parameterParserHelper.ParseResponseTypes(authorizationParameter.ResponseType); if (!responseTypes.Any()) { throw new IdentityServerExceptionWithState( ErrorCodes.InvalidRequestCode, string.Format(ErrorDescriptions.MissingParameter, Constants.StandardAuthorizationRequestParameterNames.ResponseTypeName), authorizationParameter.State); } if (!_clientValidator.CheckResponseTypes(client, responseTypes.ToArray())) { throw new IdentityServerExceptionWithState( ErrorCodes.InvalidRequestCode, string.Format(ErrorDescriptions.TheClientDoesntSupportTheResponseType, authorizationParameter.ClientId, string.Join(",", responseTypes)), authorizationParameter.State); } // Check if the user connection is still valid. if (endUserIsAuthenticated && !authorizationParameter.MaxAge.Equals(default(double))) { var authenticationDateTimeClaim = claimsPrincipal.Claims.FirstOrDefault(c => c.Type == ClaimTypes.AuthenticationInstant); if (authenticationDateTimeClaim != null) { var maxAge = authorizationParameter.MaxAge; var currentDateTimeUtc = DateTimeOffset.UtcNow.ConvertToUnixTimestamp(); var authenticationDateTime = long.Parse(authenticationDateTimeClaim.Value); if (maxAge < currentDateTimeUtc - authenticationDateTime) { result = _actionResultFactory.CreateAnEmptyActionResultWithRedirection(); result.RedirectInstruction.Action = IdentityServerEndPoints.AuthenticateIndex; } } } if (result == null) { result = ProcessPromptParameters( prompts, claimsPrincipal, authorizationParameter, confirmedConsent); await ProcessIdTokenHint(result, authorizationParameter, prompts, claimsPrincipal, issuerName); } var actionTypeName = Enum.GetName(typeof(TypeActionResult), result.Type); var actionName = result.RedirectInstruction == null ? string.Empty : Enum.GetName(typeof(IdentityServerEndPoints), result.RedirectInstruction.Action); _oauthEventSource.EndProcessingAuthorizationRequest( serializedAuthorizationParameter, actionTypeName, actionName); return(result); }