Пример #1
0
        public async Task <GrantedToken> Execute(RefreshTokenGrantTypeParameter refreshTokenGrantTypeParameter)
        {
            if (refreshTokenGrantTypeParameter == null)
            {
                throw new ArgumentNullException(nameof(refreshTokenGrantTypeParameter));
            }

            // 1. Validate parameters
            var grantedToken = await ValidateParameter(refreshTokenGrantTypeParameter);

            // 2. Generate a new access token & insert it
            var generatedToken = await _grantedTokenGeneratorHelper.GenerateTokenAsync(
                grantedToken.ClientId,
                grantedToken.Scope,
                grantedToken.UserInfoPayLoad,
                grantedToken.IdTokenPayLoad);

            generatedToken.ParentTokenId = grantedToken.Id;
            // 3. Fill-in the idtoken
            if (generatedToken.IdTokenPayLoad != null)
            {
                await _jwtGenerator.UpdatePayloadDate(generatedToken.IdTokenPayLoad);

                generatedToken.IdToken = await _clientHelper.GenerateIdTokenAsync(generatedToken.ClientId, generatedToken.IdTokenPayLoad);
            }

            await _tokenStore.AddToken(generatedToken);

            _simpleIdentityServerEventSource.GrantAccessToClient(generatedToken.ClientId,
                                                                 generatedToken.AccessToken,
                                                                 generatedToken.Scope);
            return(generatedToken);
        }
        public async Task <GrantedToken> Execute(RefreshTokenGrantTypeParameter refreshTokenGrantTypeParameter, AuthenticationHeaderValue authenticationHeaderValue, X509Certificate2 certificate, string issuerName)
        {
            if (refreshTokenGrantTypeParameter == null)
            {
                throw new ArgumentNullException(nameof(refreshTokenGrantTypeParameter));
            }

            // 1. Try to authenticate the client
            var instruction = CreateAuthenticateInstruction(refreshTokenGrantTypeParameter, authenticationHeaderValue, certificate);
            var authResult  = await _authenticateClient.AuthenticateAsync(instruction, issuerName);

            var client = authResult.Client;

            if (authResult.Client == null)
            {
                _oauthEventSource.Info(authResult.ErrorMessage);
                throw new IdentityServerException(ErrorCodes.InvalidClient, authResult.ErrorMessage);
            }

            // 2. Check client
            if (client.GrantTypes == null || !client.GrantTypes.Contains(GrantType.refresh_token))
            {
                throw new IdentityServerException(ErrorCodes.InvalidClient,
                                                  string.Format(ErrorDescriptions.TheClientDoesntSupportTheGrantType, client.ClientId, GrantType.refresh_token));
            }

            // 3. Validate parameters
            var grantedToken = await ValidateParameter(refreshTokenGrantTypeParameter);

            if (grantedToken.ClientId != client.ClientId)
            {
                throw new IdentityServerException(ErrorCodes.InvalidGrant, ErrorDescriptions.TheRefreshTokenCanBeUsedOnlyByTheSameIssuer);
            }

            // 4. Generate a new access token & insert it
            var generatedToken = await _grantedTokenGeneratorHelper.GenerateTokenAsync(
                grantedToken.ClientId,
                grantedToken.Scope,
                issuerName,
                grantedToken.UserInfoPayLoad,
                grantedToken.IdTokenPayLoad);

            generatedToken.ParentTokenId = grantedToken.Id;
            // 5. Fill-in the idtoken
            if (generatedToken.IdTokenPayLoad != null)
            {
                await _jwtGenerator.UpdatePayloadDate(generatedToken.IdTokenPayLoad);

                generatedToken.IdToken = await _clientHelper.GenerateIdTokenAsync(generatedToken.ClientId, generatedToken.IdTokenPayLoad);
            }

            await _tokenStore.AddToken(generatedToken);

            _oauthEventSource.GrantAccessToClient(generatedToken.ClientId,
                                                  generatedToken.AccessToken,
                                                  generatedToken.Scope);
            return(generatedToken);
        }
Пример #3
0
        public async Task <GrantedToken> Execute(
            AuthorizationCodeGrantTypeParameter authorizationCodeGrantTypeParameter,
            AuthenticationHeaderValue authenticationHeaderValue)
        {
            if (authorizationCodeGrantTypeParameter == null)
            {
                throw new ArgumentNullException(nameof(authorizationCodeGrantTypeParameter));
            }

            var result = await ValidateParameter(
                authorizationCodeGrantTypeParameter,
                authenticationHeaderValue);

            await _authorizationCodeStore.RemoveAuthorizationCode(result.AuthCode.Code); // 1. Invalidate the authorization code by removing it !

            var grantedToken = await _grantedTokenHelper.GetValidGrantedTokenAsync(
                result.AuthCode.Scopes,
                result.AuthCode.ClientId,
                result.AuthCode.IdTokenPayload,
                result.AuthCode.UserInfoPayLoad);

            if (grantedToken == null)
            {
                grantedToken = await _grantedTokenGeneratorHelper.GenerateTokenAsync(result.Client, result.AuthCode.Scopes, result.AuthCode.UserInfoPayLoad, result.AuthCode.IdTokenPayload);

                _simpleIdentityServerEventSource.GrantAccessToClient(
                    result.AuthCode.ClientId,
                    grantedToken.AccessToken,
                    grantedToken.IdToken);
                // Fill-in the id-token
                if (grantedToken.IdTokenPayLoad != null)
                {
                    await _jwtGenerator.UpdatePayloadDate(grantedToken.IdTokenPayLoad);

                    grantedToken.IdToken = await _clientHelper.GenerateIdTokenAsync(result.Client, grantedToken.IdTokenPayLoad);
                }

                await _tokenStore.AddToken(grantedToken);
            }

            return(grantedToken);
        }
Пример #4
0
        public async Task <GrantedToken> Execute(ClientCredentialsGrantTypeParameter clientCredentialsGrantTypeParameter, AuthenticationHeaderValue authenticationHeaderValue, X509Certificate2 certificate, string issuerName)
        {
            if (clientCredentialsGrantTypeParameter == null)
            {
                throw new ArgumentNullException(nameof(clientCredentialsGrantTypeParameter));
            }

            _clientCredentialsGrantTypeParameterValidator.Validate(clientCredentialsGrantTypeParameter);

            // 1. Authenticate the client
            var instruction = CreateAuthenticateInstruction(clientCredentialsGrantTypeParameter, authenticationHeaderValue, certificate);
            var authResult  = await _authenticateClient.AuthenticateAsync(instruction, issuerName);

            var client = authResult.Client;

            if (client == null)
            {
                throw new IdentityServerException(ErrorCodes.InvalidClient, authResult.ErrorMessage);
            }

            // 2. Check client
            if (client.GrantTypes == null || !client.GrantTypes.Contains(GrantType.client_credentials))
            {
                throw new IdentityServerException(ErrorCodes.InvalidClient,
                                                  string.Format(ErrorDescriptions.TheClientDoesntSupportTheGrantType, client.ClientId, GrantType.client_credentials));
            }

            if (client.ResponseTypes == null || !client.ResponseTypes.Contains(ResponseType.token))
            {
                throw new IdentityServerException(ErrorCodes.InvalidClient,
                                                  string.Format(ErrorDescriptions.TheClientDoesntSupportTheResponseType, client.ClientId, ResponseType.token));
            }

            // 3. Check scopes
            string allowedTokenScopes = string.Empty;

            if (!string.IsNullOrWhiteSpace(clientCredentialsGrantTypeParameter.Scope))
            {
                var scopeValidation = _scopeValidator.Check(clientCredentialsGrantTypeParameter.Scope, client);
                if (!scopeValidation.IsValid)
                {
                    throw new IdentityServerException(
                              ErrorCodes.InvalidScope,
                              scopeValidation.ErrorMessage);
                }

                allowedTokenScopes = string.Join(" ", scopeValidation.Scopes);
            }

            // 4. Generate the JWT access token on the fly.
            var grantedToken = await _grantedTokenHelper.GetValidGrantedTokenAsync(allowedTokenScopes, client.ClientId);

            if (grantedToken == null)
            {
                grantedToken = await _grantedTokenGeneratorHelper.GenerateTokenAsync(client, allowedTokenScopes, issuerName);

                await _tokenStore.AddToken(grantedToken);

                _oauthEventSource.GrantAccessToClient(client.ClientId, grantedToken.AccessToken, allowedTokenScopes);
            }

            return(grantedToken);
        }
Пример #5
0
        public async Task <EndpointResult> Generate(
            EndpointResult endpointResult,
            AuthorizationParameter authorizationParameter,
            ClaimsPrincipal claimsPrincipal,
            Client client,
            string?issuerName,
            CancellationToken cancellationToken)
        {
            var          allowedTokenScopes = string.Empty;
            GrantedToken?grantedToken       = null;
            var          responses          = authorizationParameter.ResponseType.ParseResponseTypes();
            var          generateIdToken    = await GenerateIdTokenPayload(
                claimsPrincipal,
                authorizationParameter,
                issuerName,
                cancellationToken)
                                              .ConfigureAwait(false);

            if (generateIdToken is Option <JwtPayload> .Result p)
            {
                var idTokenPayload = p.Item;
                var payload        = await GenerateUserInformationPayload(
                    claimsPrincipal,
                    authorizationParameter,
                    cancellationToken)
                                     .ConfigureAwait(false);

                if (payload is Option <JwtPayload> .Error er)
                {
                    return(EndpointResult.CreateBadRequestResult(er.Details));
                }

                var userInformationPayload = (payload as Option <JwtPayload> .Result) !.Item;
                if (responses.Contains(ResponseTypeNames.Token))
                {
                    // 1. Generate an access token.

                    var tokenScopes = authorizationParameter.Scope.ParseScopes();
                    allowedTokenScopes = string.Join(' ', tokenScopes);
                    grantedToken       = await _tokenStore.GetValidGrantedToken(
                        _jwksStore,
                        allowedTokenScopes,
                        client.ClientId,
                        cancellationToken,
                        idTokenJwsPayload : userInformationPayload,
                        userInfoJwsPayload : idTokenPayload)
                                         .ConfigureAwait(false)
                                         ?? await client.GenerateToken(
                        _jwksStore,
                        tokenScopes,
                        issuerName,
                        userInformationPayload,
                        idTokenPayload,
                        cancellationToken : cancellationToken,
                        claimsPrincipal.Claims.Where(
                            c => client.UserClaimsToIncludeInAuthToken.Any(
                                r => r.IsMatch(c.Type)))
                        .ToArray())
                                         .ConfigureAwait(false);

                    endpointResult = endpointResult with
                    {
                        RedirectInstruction = endpointResult.RedirectInstruction !.AddParameter(
                            StandardAuthorizationResponseNames.AccessTokenName,
                            grantedToken.AccessToken)
                    };
                }

                AuthorizationCode?authorizationCode = null;
                var authorizationParameterClientId  = authorizationParameter.ClientId;
                if (responses.Contains(ResponseTypeNames.Code)) // 2. Generate an authorization code.
                {
                    var subject         = claimsPrincipal.GetSubject() !;
                    var assignedConsent = await _consentRepository
                                          .GetConfirmedConsents(subject, authorizationParameter, cancellationToken)
                                          .ConfigureAwait(false);

                    if (assignedConsent != null)
                    {
                        if (authorizationParameterClientId == null ||
                            authorizationParameter.RedirectUrl == null ||
                            authorizationParameter.Scope == null)
                        {
                            throw new ArgumentException(Strings.MissingValues, nameof(authorizationParameter));
                        }

                        // Insert a temporary authorization code
                        // It will be used later to retrieve tha id_token or an access token.
                        authorizationCode = new AuthorizationCode
                        {
                            Code            = Id.Create(),
                            RedirectUri     = authorizationParameter.RedirectUrl,
                            CreateDateTime  = DateTimeOffset.UtcNow,
                            ClientId        = authorizationParameterClientId,
                            Scopes          = authorizationParameter.Scope,
                            IdTokenPayload  = idTokenPayload,
                            UserInfoPayLoad = userInformationPayload
                        };

                        endpointResult = endpointResult with
                        {
                            RedirectInstruction = endpointResult.RedirectInstruction !.AddParameter(
                                StandardAuthorizationResponseNames.AuthorizationCodeName,
                                authorizationCode.Code)
                        };
                    }
                }

                _jwtGenerator.FillInOtherClaimsIdentityTokenPayload(
                    idTokenPayload,
                    authorizationCode == null ? string.Empty : authorizationCode.Code,
                    grantedToken == null ? string.Empty : grantedToken.AccessToken,
                    client);

                if (grantedToken != null)
                // 3. Insert the stateful access token into the DB OR insert the access token into the caching.
                {
                    if (authorizationParameterClientId == null || authorizationParameter.ResponseType == null)
                    {
                        throw new ArgumentException(Strings.MissingValues, nameof(authorizationParameter));
                    }

                    await _tokenStore.AddToken(grantedToken, cancellationToken).ConfigureAwait(false);

                    await _eventPublisher.Publish(
                        new TokenGranted(
                            Id.Create(),
                            claimsPrincipal.GetSubject(),
                            authorizationParameterClientId,
                            allowedTokenScopes,
                            authorizationParameter.ResponseType,
                            DateTimeOffset.UtcNow))
                    .ConfigureAwait(false);
                }

                if (authorizationCode != null) // 4. Insert the authorization code into the caching.
                {
                    if (client.RequirePkce)
                    {
                        authorizationCode = authorizationCode with
                        {
                            CodeChallenge       = authorizationParameter.CodeChallenge ?? string.Empty,
                            CodeChallengeMethod = authorizationParameter.CodeChallengeMethod ?? string.Empty
                        };
                    }

                    await _authorizationCodeStore.Add(authorizationCode, cancellationToken).ConfigureAwait(false);

                    await _eventPublisher.Publish(
                        new AuthorizationGranted(
                            Id.Create(),
                            claimsPrincipal.GetSubject(),
                            authorizationParameterClientId !,
                            DateTimeOffset.UtcNow))
                    .ConfigureAwait(false);
                }

                if (responses.Contains(ResponseTypeNames.IdToken))
                {
                    var idToken = await _clientStore.GenerateIdToken(
                        authorizationParameterClientId !,
                        idTokenPayload,
                        _jwksStore,
                        cancellationToken)
                                  .ConfigureAwait(false);

                    endpointResult = endpointResult with
                    {
                        RedirectInstruction = endpointResult.RedirectInstruction !.AddParameter(
                            StandardAuthorizationResponseNames.IdTokenName,
                            idToken)
                    };
                }

                if (!string.IsNullOrWhiteSpace(authorizationParameter.State))
                {
                    endpointResult = endpointResult with
                    {
                        RedirectInstruction = endpointResult.RedirectInstruction !.AddParameter(
                            StandardAuthorizationResponseNames.StateName,
                            authorizationParameter.State)
                    };
                }

                var sessionState = GetSessionState(
                    authorizationParameterClientId,
                    authorizationParameter.OriginUrl,
                    authorizationParameter.SessionId);
                if (sessionState != null)
                {
                    endpointResult = endpointResult with
                    {
                        RedirectInstruction = endpointResult.RedirectInstruction !.AddParameter(
                            StandardAuthorizationResponseNames.SessionState,
                            sessionState)
                    };
                }

                if (authorizationParameter.ResponseMode == ResponseModes.FormPost)
                {
                    endpointResult = endpointResult with
                    {
                        Type = ActionResultType.RedirectToAction,
                        RedirectInstruction = endpointResult.RedirectInstruction !.AddParameter(
                            "redirect_uri",
                            authorizationParameter.RedirectUrl?.AbsoluteUri) with
                        {
                            Action = SimpleAuthEndPoints.FormIndex
                        }
                    };
                }

                // Set the response mode
                if (endpointResult.Type == ActionResultType.RedirectToCallBackUrl)
                {
                    var responseMode = authorizationParameter.ResponseMode;
                    if (responseMode == ResponseModes.None)
                    {
                        var responseTypes     = authorizationParameter.ResponseType.ParseResponseTypes();
                        var authorizationFlow = responseTypes.GetAuthorizationFlow(authorizationParameter.State);
                        switch (authorizationFlow)
                        {
                        case Option <AuthorizationFlow> .Error error:
                            return(EndpointResult.CreateBadRequestResult(error.Details));

                        case Option <AuthorizationFlow> .Result r:
                            responseMode = CoreConstants.MappingAuthorizationFlowAndResponseModes[r.Item];
                            break;
                        }
                    }

                    endpointResult = endpointResult with
                    {
                        RedirectInstruction = endpointResult.RedirectInstruction !with {
                            ResponseMode = responseMode
                        }
                    };
                }

                return(endpointResult);
            }
            var e = generateIdToken as Option <JwtPayload> .Error;

            return(EndpointResult.CreateBadRequestResult(e !.Details));
        }
Пример #6
0
        public async Task <GrantedToken> Execute(GetTokenViaTicketIdParameter parameter, AuthenticationHeaderValue authenticationHeaderValue, X509Certificate2 certificate, string issuerName)
        {
            // 1. Check parameters.
            if (parameter == null)
            {
                throw new ArgumentNullException(nameof(parameter));
            }

            if (string.IsNullOrWhiteSpace(parameter.Ticket))
            {
                throw new BaseUmaException(ErrorCodes.InvalidRequestCode, string.Format(ErrorDescriptions.TheParameterNeedsToBeSpecified, PostAuthorizationNames.TicketId));
            }

            if (string.IsNullOrWhiteSpace(parameter.Ticket))
            {
                throw new ArgumentNullException(nameof(parameter.Ticket));
            }

            // 2. Try to authenticate the client.
            var instruction = CreateAuthenticateInstruction(parameter, authenticationHeaderValue, certificate);
            var authResult  = await _authenticateClient.AuthenticateAsync(instruction, issuerName);

            var client = authResult.Client;

            if (client == null)
            {
                throw new BaseUmaException(ErrorCodes.InvalidClient, authResult.ErrorMessage);
            }

            if (client.GrantTypes == null || !client.GrantTypes.Contains(GrantType.uma_ticket))
            {
                throw new BaseUmaException(ErrorCodes.InvalidGrant, string.Format(ErrorDescriptions.TheClientDoesntSupportTheGrantType, client.ClientId, GrantType.uma_ticket));
            }

            // 3. Retrieve the ticket.
            var json = JsonConvert.SerializeObject(parameter);

            _umaServerEventSource.StartGettingAuthorization(json);
            var ticket = await _ticketStore.GetAsync(parameter.Ticket);

            if (ticket == null)
            {
                throw new BaseUmaException(ErrorCodes.InvalidTicket, string.Format(ErrorDescriptions.TheTicketDoesntExist, parameter.Ticket));
            }

            // 4. Check the ticket.
            if (ticket.ExpirationDateTime < DateTime.UtcNow)
            {
                throw new BaseUmaException(ErrorCodes.ExpiredTicket, ErrorDescriptions.TheTicketIsExpired);
            }

            _umaServerEventSource.CheckAuthorizationPolicy(json);
            var claimTokenParameter = new ClaimTokenParameter
            {
                Token  = parameter.ClaimToken,
                Format = parameter.ClaimTokenFormat
            };

            // 4. Check the authorization.
            var authorizationResult = await _authorizationPolicyValidator.IsAuthorized(ticket, client.ClientId, claimTokenParameter);

            if (authorizationResult.Type != AuthorizationPolicyResultEnum.Authorized)
            {
                _umaServerEventSource.RequestIsNotAuthorized(json);
                throw new BaseUmaException(ErrorCodes.InvalidGrant, ErrorDescriptions.TheAuthorizationPolicyIsNotSatisfied);
            }

            // 5. Generate a granted token.
            var grantedToken = await GenerateTokenAsync(client, ticket.Lines, "openid", issuerName);

            await _tokenStore.AddToken(grantedToken);

            await _ticketStore.RemoveAsync(ticket.Id);

            return(grantedToken);
        }
Пример #7
0
        public async Task <GrantedToken> Execute(ResourceOwnerGrantTypeParameter resourceOwnerGrantTypeParameter, AuthenticationHeaderValue authenticationHeaderValue, X509Certificate2 certificate = null)
        {
            if (resourceOwnerGrantTypeParameter == null)
            {
                throw new ArgumentNullException(nameof(resourceOwnerGrantTypeParameter));
            }

            // 1. Try to authenticate the client
            var instruction = CreateAuthenticateInstruction(resourceOwnerGrantTypeParameter, authenticationHeaderValue, certificate);
            var authResult  = await _authenticateClient.AuthenticateAsync(instruction);

            var client = authResult.Client;

            if (authResult.Client == null)
            {
                _simpleIdentityServerEventSource.Info(ErrorDescriptions.TheClientCannotBeAuthenticated);
                client = await _clientRepository.GetClientByIdAsync(Constants.AnonymousClientId);

                if (client == null)
                {
                    throw new IdentityServerException(ErrorCodes.InternalError, string.Format(ErrorDescriptions.ClientIsNotValid, Constants.AnonymousClientId));
                }
            }

            // 2. Try to authenticate a resource owner
            var resourceOwner = await _authenticateResourceOwnerService.AuthenticateResourceOwnerAsync(resourceOwnerGrantTypeParameter.UserName, resourceOwnerGrantTypeParameter.Password);

            if (resourceOwner == null)
            {
                throw new IdentityServerException(ErrorCodes.InvalidGrant, ErrorDescriptions.ResourceOwnerCredentialsAreNotValid);
            }

            // 3. Check if the requested scopes are valid
            var allowedTokenScopes = string.Empty;

            if (!string.IsNullOrWhiteSpace(resourceOwnerGrantTypeParameter.Scope))
            {
                var scopeValidation = _scopeValidator.Check(resourceOwnerGrantTypeParameter.Scope, client);
                if (!scopeValidation.IsValid)
                {
                    throw new IdentityServerException(ErrorCodes.InvalidScope, scopeValidation.ErrorMessage);
                }

                allowedTokenScopes = string.Join(" ", scopeValidation.Scopes);
            }

            // 4. Generate the user information payload and store it.
            var claims                 = resourceOwner.Claims;
            var claimsIdentity         = new ClaimsIdentity(claims, "simpleIdentityServer");
            var claimsPrincipal        = new ClaimsPrincipal(claimsIdentity);
            var authorizationParameter = new AuthorizationParameter
            {
                Scope = resourceOwnerGrantTypeParameter.Scope
            };
            var payload = await _jwtGenerator.GenerateUserInfoPayloadForScopeAsync(claimsPrincipal, authorizationParameter);

            var generatedToken = await _grantedTokenHelper.GetValidGrantedTokenAsync(allowedTokenScopes, client.ClientId, payload, payload);

            if (generatedToken == null)
            {
                generatedToken = await _grantedTokenGeneratorHelper.GenerateTokenAsync(client, allowedTokenScopes, payload, payload);

                if (generatedToken.IdTokenPayLoad != null)
                {
                    await _jwtGenerator.UpdatePayloadDate(generatedToken.IdTokenPayLoad);

                    generatedToken.IdToken = await _clientHelper.GenerateIdTokenAsync(client, generatedToken.IdTokenPayLoad);
                }

                await _tokenStore.AddToken(generatedToken);

                _simpleIdentityServerEventSource.GrantAccessToClient(client.ClientId, generatedToken.AccessToken, allowedTokenScopes);
            }

            return(generatedToken);
        }
Пример #8
0
        public async Task <GrantedToken> Execute(ResourceOwnerGrantTypeParameter resourceOwnerGrantTypeParameter, AuthenticationHeaderValue authenticationHeaderValue, X509Certificate2 certificate, string issuerName)
        {
            if (resourceOwnerGrantTypeParameter == null)
            {
                throw new ArgumentNullException(nameof(resourceOwnerGrantTypeParameter));
            }

            // 1. Try to authenticate the client
            var instruction = CreateAuthenticateInstruction(resourceOwnerGrantTypeParameter, authenticationHeaderValue, certificate);
            var authResult  = await _authenticateClient.AuthenticateAsync(instruction, issuerName);

            var client = authResult.Client;

            if (authResult.Client == null)
            {
                _oauthEventSource.Info(authResult.ErrorMessage);
                throw new IdentityServerException(ErrorCodes.InvalidClient, authResult.ErrorMessage);
            }

            // 2. Check the client.
            if (client.GrantTypes == null || !client.GrantTypes.Contains(GrantType.password))
            {
                throw new IdentityServerException(ErrorCodes.InvalidClient,
                                                  string.Format(ErrorDescriptions.TheClientDoesntSupportTheGrantType, client.ClientId, GrantType.password));
            }

            if (client.ResponseTypes == null || !client.ResponseTypes.Contains(ResponseType.token) || !client.ResponseTypes.Contains(ResponseType.id_token))
            {
                throw new IdentityServerException(ErrorCodes.InvalidClient, string.Format(ErrorDescriptions.TheClientDoesntSupportTheResponseType, client.ClientId, "token id_token"));
            }

            // 3. Try to authenticate a resource owner
            var resourceOwner = await _resourceOwnerAuthenticateHelper.Authenticate(resourceOwnerGrantTypeParameter.UserName,
                                                                                    resourceOwnerGrantTypeParameter.Password,
                                                                                    resourceOwnerGrantTypeParameter.AmrValues);

            if (resourceOwner == null)
            {
                throw new IdentityServerException(ErrorCodes.InvalidGrant, ErrorDescriptions.ResourceOwnerCredentialsAreNotValid);
            }

            // 4. Check if the requested scopes are valid
            var allowedTokenScopes = string.Empty;

            if (!string.IsNullOrWhiteSpace(resourceOwnerGrantTypeParameter.Scope))
            {
                var scopeValidation = _scopeValidator.Check(resourceOwnerGrantTypeParameter.Scope, client);
                if (!scopeValidation.IsValid)
                {
                    throw new IdentityServerException(ErrorCodes.InvalidScope, scopeValidation.ErrorMessage);
                }

                allowedTokenScopes = string.Join(" ", scopeValidation.Scopes);
            }

            // 5. Generate the user information payload and store it.
            var claims                 = resourceOwner.Claims;
            var claimsIdentity         = new ClaimsIdentity(claims, "simpleIdentityServer");
            var claimsPrincipal        = new ClaimsPrincipal(claimsIdentity);
            var authorizationParameter = new AuthorizationParameter
            {
                Scope = resourceOwnerGrantTypeParameter.Scope
            };
            var payload = await _jwtGenerator.GenerateIdTokenPayloadForScopesAsync(claimsPrincipal, authorizationParameter, issuerName);

            var generatedToken = await _grantedTokenHelper.GetValidGrantedTokenAsync(allowedTokenScopes, client.ClientId, payload, payload);

            if (generatedToken == null)
            {
                generatedToken = await _grantedTokenGeneratorHelper.GenerateTokenAsync(client, allowedTokenScopes, issuerName, payload, payload);

                if (generatedToken.IdTokenPayLoad != null)
                {
                    await _jwtGenerator.UpdatePayloadDate(generatedToken.IdTokenPayLoad);

                    generatedToken.IdToken = await _clientHelper.GenerateIdTokenAsync(client, generatedToken.IdTokenPayLoad);
                }

                await _tokenStore.AddToken(generatedToken);

                _oauthEventSource.GrantAccessToClient(client.ClientId, generatedToken.AccessToken, allowedTokenScopes);
            }

            return(generatedToken);
        }
        public async Task ExecuteAsync(ActionResult actionResult, AuthorizationParameter authorizationParameter, ClaimsPrincipal claimsPrincipal, Client client)
        {
            if (actionResult == null || actionResult.RedirectInstruction == null)
            {
                throw new ArgumentNullException(nameof(actionResult));
            }
            ;
            if (authorizationParameter == null)
            {
                throw new ArgumentNullException(nameof(authorizationParameter));
            }

            if (claimsPrincipal == null)
            {
                throw new ArgumentNullException(nameof(claimsPrincipal));
            }

            if (client == null)
            {
                throw new ArgumentNullException(nameof(client));
            }

            var               newAccessTokenGranted       = false;
            var               allowedTokenScopes          = string.Empty;
            GrantedToken      grantedToken                = null;
            var               newAuthorizationCodeGranted = false;
            AuthorizationCode authorizationCode           = null;

            _simpleIdentityServerEventSource.StartGeneratingAuthorizationResponseToClient(authorizationParameter.ClientId,
                                                                                          authorizationParameter.ResponseType);
            var responses      = _parameterParserHelper.ParseResponseTypes(authorizationParameter.ResponseType);
            var idTokenPayload = await GenerateIdTokenPayload(claimsPrincipal, authorizationParameter);

            var userInformationPayload = await GenerateUserInformationPayload(claimsPrincipal, authorizationParameter);

            if (responses.Contains(ResponseType.token)) // 1. Generate an access token.
            {
                if (!string.IsNullOrWhiteSpace(authorizationParameter.Scope))
                {
                    allowedTokenScopes = string.Join(" ", _parameterParserHelper.ParseScopes(authorizationParameter.Scope));
                }


                grantedToken = await _grantedTokenHelper.GetValidGrantedTokenAsync(allowedTokenScopes, client.ClientId,
                                                                                   userInformationPayload, idTokenPayload);

                if (grantedToken == null)
                {
                    grantedToken = await _grantedTokenGeneratorHelper.GenerateTokenAsync(client, allowedTokenScopes,
                                                                                         userInformationPayload, idTokenPayload);

                    newAccessTokenGranted = true;
                }

                actionResult.RedirectInstruction.AddParameter(Constants.StandardAuthorizationResponseNames.AccessTokenName,
                                                              grantedToken.AccessToken);
            }

            if (responses.Contains(ResponseType.code)) // 2. Generate an authorization code.
            {
                var subject         = claimsPrincipal == null ? string.Empty : claimsPrincipal.GetSubject();
                var assignedConsent = await _consentHelper.GetConfirmedConsentsAsync(subject, authorizationParameter);

                if (assignedConsent != null)
                {
                    // Insert a temporary authorization code
                    // It will be used later to retrieve tha id_token or an access token.
                    authorizationCode = new AuthorizationCode
                    {
                        Code            = Guid.NewGuid().ToString(),
                        RedirectUri     = authorizationParameter.RedirectUrl,
                        CreateDateTime  = DateTime.UtcNow,
                        ClientId        = authorizationParameter.ClientId,
                        Scopes          = authorizationParameter.Scope,
                        IdTokenPayload  = idTokenPayload,
                        UserInfoPayLoad = userInformationPayload
                    };

                    newAuthorizationCodeGranted = true;
                    actionResult.RedirectInstruction.AddParameter(Constants.StandardAuthorizationResponseNames.AuthorizationCodeName,
                                                                  authorizationCode.Code);
                }
            }

            _jwtGenerator.FillInOtherClaimsIdentityTokenPayload(idTokenPayload,
                                                                authorizationCode == null ? string.Empty : authorizationCode.Code,
                                                                grantedToken == null ? string.Empty : grantedToken.AccessToken,
                                                                authorizationParameter, client);

            if (newAccessTokenGranted) // 3. Insert the stateful access token into the DB OR insert the access token into the caching.
            {
                await _tokenStore.AddToken(grantedToken);

                _simpleIdentityServerEventSource.GrantAccessToClient(authorizationParameter.ClientId,
                                                                     grantedToken.AccessToken,
                                                                     allowedTokenScopes);
            }

            if (newAuthorizationCodeGranted) // 4. Insert the authorization code into the caching.
            {
                if (client.RequirePkce)
                {
                    authorizationCode.CodeChallenge       = authorizationParameter.CodeChallenge;
                    authorizationCode.CodeChallengeMethod = authorizationParameter.CodeChallengeMethod;
                }

                await _authorizationCodeStore.AddAuthorizationCode(authorizationCode);

                _simpleIdentityServerEventSource.GrantAuthorizationCodeToClient(authorizationParameter.ClientId,
                                                                                authorizationCode.Code,
                                                                                authorizationParameter.Scope);
            }

            if (responses.Contains(ResponseType.id_token))
            {
                var idToken = await GenerateIdToken(idTokenPayload, authorizationParameter);

                actionResult.RedirectInstruction.AddParameter(Constants.StandardAuthorizationResponseNames.IdTokenName, idToken);
            }

            if (!string.IsNullOrWhiteSpace(authorizationParameter.State))
            {
                actionResult.RedirectInstruction.AddParameter(Constants.StandardAuthorizationResponseNames.StateName, authorizationParameter.State);
            }

            var sessionState = GetSessionState(authorizationParameter.ClientId, authorizationParameter.OriginUrl, authorizationParameter.SessionId);

            if (sessionState != null)
            {
                actionResult.RedirectInstruction.AddParameter(Constants.StandardAuthorizationResponseNames.SessionState, sessionState);
            }

            if (authorizationParameter.ResponseMode == ResponseMode.form_post)
            {
                actionResult.Type = TypeActionResult.RedirectToAction;
                actionResult.RedirectInstruction.Action = IdentityServerEndPoints.FormIndex;
                actionResult.RedirectInstruction.AddParameter("redirect_uri", authorizationParameter.RedirectUrl);
            }

            // Set the response mode
            if (actionResult.Type == TypeActionResult.RedirectToCallBackUrl)
            {
                var responseMode = authorizationParameter.ResponseMode;
                if (responseMode == ResponseMode.None)
                {
                    var responseTypes     = _parameterParserHelper.ParseResponseTypes(authorizationParameter.ResponseType);
                    var authorizationFlow = _authorizationFlowHelper.GetAuthorizationFlow(responseTypes,
                                                                                          authorizationParameter.State);
                    responseMode = GetResponseMode(authorizationFlow);
                }

                actionResult.RedirectInstruction.ResponseMode = responseMode;
            }

            _simpleIdentityServerEventSource.EndGeneratingAuthorizationResponseToClient(authorizationParameter.ClientId,
                                                                                        actionResult.RedirectInstruction.Parameters.SerializeWithJavascript());
        }
        public async Task <GetTokenByTicketIdResponse> Execute(GetTokenViaTicketIdParameter parameter, string openidProvider, string issuerName)
        {
            // 1. Check parameters.
            if (parameter == null)
            {
                throw new ArgumentNullException(nameof(parameter));
            }

            if (string.IsNullOrWhiteSpace(parameter.Ticket))
            {
                throw new BaseUmaException(ErrorCodes.InvalidRequestCode, string.Format(ErrorDescriptions.TheParameterNeedsToBeSpecified, PostAuthorizationNames.TicketId));
            }

            if (string.IsNullOrWhiteSpace(parameter.Ticket))
            {
                throw new ArgumentNullException(nameof(parameter.Ticket));
            }

            if (string.IsNullOrWhiteSpace(openidProvider))
            {
                throw new ArgumentNullException(nameof(openidProvider));
            }

            // 2. Retrieve the ticket.
            var json = JsonConvert.SerializeObject(parameter);

            _umaServerEventSource.StartGettingAuthorization(json);
            var ticket = await _ticketStore.GetAsync(parameter.Ticket).ConfigureAwait(false);

            if (ticket == null)
            {
                throw new BaseUmaException(ErrorCodes.InvalidTicket, string.Format(ErrorDescriptions.TheTicketDoesntExist, parameter.Ticket));
            }

            // 3. Check the ticket.
            if (ticket.ExpirationDateTime < DateTime.UtcNow)
            {
                throw new BaseUmaException(ErrorCodes.ExpiredTicket, ErrorDescriptions.TheTicketIsExpired);
            }

            _umaServerEventSource.CheckAuthorizationPolicy(json);
            var claimTokenParameter = new ClaimTokenParameter
            {
                Token  = parameter.ClaimToken,
                Format = parameter.ClaimTokenFormat
            };

            // 4. Check the authorization.
            var authorizationResult = await _authorizationPolicyValidator.IsAuthorized(openidProvider, ticket, claimTokenParameter).ConfigureAwait(false);

            if (!authorizationResult.IsValid)
            {
                _umaServerEventSource.RequestIsNotAuthorized(json);
                return(new GetTokenByTicketIdResponse
                {
                    IsValid = false,
                    ResourceValidationResult = authorizationResult
                });
            }

            // 5. Generate a granted token.
            var grantedToken = await GenerateTokenAsync(ticket.Audiences, ticket.Lines, "openid", issuerName).ConfigureAwait(false);

            await _tokenStore.AddToken(grantedToken);

            await _ticketStore.RemoveAsync(ticket.Id);

            return(new GetTokenByTicketIdResponse
            {
                IsValid = true,
                GrantedToken = grantedToken
            });
        }