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());
        }
コード例 #4
0
        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);
        }