Exemple #1
0
        [HttpGet(Constants.RouteNames.UserClaims)] // User Authentication enabled.
        public async Task <IActionResult> GetClaims()
        {
            // 1. Get the subject.
            var subjectResult = await GetSubject();

            if (!subjectResult.IsValid)
            {
                return(subjectResult.Error);
            }

            // 2. Get the user.
            var user = await _resourceOwnerRepository.GetAsync(subjectResult.Subject);

            if (user == null)
            {
                return(this.BuildError(ErrorCodes.InvalidRequestCode, ErrorDescriptions.TheRoDoesntExist, HttpStatusCode.NotFound));
            }

            var jObj = new JObject();

            foreach (var claim in user.Claims)
            {
                jObj.Add(claim.Type, claim.Value);
            }

            return(new OkObjectResult(jObj));
        }
Exemple #2
0
        public async Task <ResourceOwner> AuthenticateResourceOwnerAsync(string login)
        {
            if (string.IsNullOrWhiteSpace(login))
            {
                throw new ArgumentNullException(nameof(login));
            }

            return(await _resourceOwnerRepository.GetAsync(login));
        }
        public Task <ResourceOwner> Execute(ClaimsPrincipal claimsPrincipal)
        {
            if (claimsPrincipal == null)
            {
                throw new ArgumentNullException(nameof(claimsPrincipal));
            }

            if (claimsPrincipal.Identity == null ||
                !claimsPrincipal.Identity.IsAuthenticated ||
                !(claimsPrincipal.Identity is ClaimsIdentity))
            {
                throw new IdentityServerException(
                          Errors.ErrorCodes.UnhandledExceptionCode,
                          Errors.ErrorDescriptions.TheUserNeedsToBeAuthenticated);
            }

            var subject = claimsPrincipal.GetSubject();

            if (string.IsNullOrWhiteSpace(subject))
            {
                throw new IdentityServerException(
                          Errors.ErrorCodes.UnhandledExceptionCode,
                          Errors.ErrorDescriptions.TheSubjectCannotBeRetrieved);
            }

            return(_resourceOwnerRepository.GetAsync(subject));
        }
        public async Task <bool> Execute(string localSubject, string externalSubject)
        {
            if (string.IsNullOrWhiteSpace(localSubject))
            {
                throw new ArgumentNullException(nameof(localSubject));
            }

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

            var resourceOwner = await _resourceOwnerRepository.GetAsync(localSubject);

            if (resourceOwner == null)
            {
                throw new IdentityServerException(Errors.ErrorCodes.InternalError, Errors.ErrorDescriptions.TheResourceOwnerDoesntExist);
            }

            var profile = await _profileRepository.Get(externalSubject);

            if (profile == null || profile.ResourceOwnerId != localSubject)
            {
                throw new IdentityServerException(Errors.ErrorCodes.InternalError, Errors.ErrorDescriptions.NotAuthorizedToRemoveTheProfile);
            }

            if (profile.Subject == localSubject)
            {
                throw new IdentityServerException(Errors.ErrorCodes.InternalError, Errors.ErrorDescriptions.TheExternalAccountAccountCannotBeUnlinked);
            }

            return(await _profileRepository.Remove(new[] { externalSubject }));
        }
        public async Task <bool> Execute(string subject)
        {
            _managerEventSource.StartToRemoveResourceOwner(subject);
            if (string.IsNullOrWhiteSpace(subject))
            {
                throw new ArgumentNullException(nameof(subject));
            }

            var resourceOwner = await _resourceOwnerRepository.GetAsync(subject);

            if (resourceOwner == null)
            {
                throw new IdentityServerManagerException(ErrorCodes.InvalidRequestCode,
                                                         string.Format(ErrorDescriptions.TheResourceOwnerDoesntExist, subject));
            }


            var res = await _resourceOwnerRepository.DeleteAsync(subject);

            if (res)
            {
                _managerEventSource.FinishToRemoveResourceOwner(subject);
            }

            return(res);
        }
        public async Task <bool> Execute(ResourceOwner parameter)
        {
            if (parameter == null)
            {
                throw new ArgumentNullException(nameof(parameter));
            }

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

            if (await _resourceOwnerRepository.GetAsync(parameter.Id) == null)
            {
                throw new IdentityServerManagerException(
                          ErrorCodes.InvalidParameterCode,
                          string.Format(ErrorDescriptions.TheResourceOwnerDoesntExist, parameter.Id));
            }

            if (parameter.Claims != null)
            {
                Claim updatedClaim;
                if (((updatedClaim = parameter.Claims.FirstOrDefault(c => c.Type == SimpleIdentityServer.Core.Jwt.Constants.StandardResourceOwnerClaimNames.UpdatedAt)) != null))
                {
                    parameter.Claims.Remove(updatedClaim);
                }

                parameter.Claims.Add(new Claim(SimpleIdentityServer.Core.Jwt.Constants.StandardResourceOwnerClaimNames.UpdatedAt, DateTime.UtcNow.ToString()));
            }

            return(await _resourceOwnerRepository.UpdateAsync(parameter));
        }
        public async Task <ResourceOwner> Execute(LocalAuthenticateParameter parameter, string imagePath, string hostUrl)
        {
            if (parameter == null)
            {
                throw new ArgumentNullException(nameof(parameter));
            }

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

            var xmlDocument = new XmlDocument();

            xmlDocument.LoadXml(parameter.Xml);
            CheckXmlWellFormed(xmlDocument);
            var resourceOwner         = ExtractResourceOwner(xmlDocument, imagePath, hostUrl);
            var existingResourceowner = await _resourceOwnerRepository.GetAsync(resourceOwner.Id);

            if (existingResourceowner == null)
            {
                await _resourceOwnerRepository.InsertAsync(resourceOwner);
            }

            return(resourceOwner);
        }
Exemple #8
0
        public async Task <bool> Execute(UpdateResourceOwnerClaimsParameter request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            var resourceOwner = await _resourceOwnerRepository.GetAsync(request.Login);

            if (resourceOwner == null)
            {
                throw new IdentityServerManagerException(ErrorCodes.InvalidParameterCode, string.Format(ErrorDescriptions.TheResourceOwnerDoesntExist, request.Login));
            }

            resourceOwner.UpdateDateTime = DateTime.UtcNow;
            var claims         = new List <Claim>();
            var existingClaims = await _claimRepository.GetAllAsync();

            if (existingClaims != null && existingClaims.Any() && request.Claims != null && request.Claims.Any())
            {
                foreach (var claim in request.Claims)
                {
                    var cl = existingClaims.FirstOrDefault(c => c.Code == claim.Key);
                    if (cl == null)
                    {
                        continue;
                    }

                    claims.Add(new Claim(claim.Key, claim.Value));
                }
            }

            resourceOwner.Claims = claims;
            Claim updatedClaim, subjectClaim;

            if (((updatedClaim = resourceOwner.Claims.FirstOrDefault(c => c.Type == SimpleIdentityServer.Core.Jwt.Constants.StandardResourceOwnerClaimNames.UpdatedAt)) != null))
            {
                resourceOwner.Claims.Remove(updatedClaim);
            }

            if (((subjectClaim = resourceOwner.Claims.FirstOrDefault(c => c.Type == SimpleIdentityServer.Core.Jwt.Constants.StandardResourceOwnerClaimNames.Subject)) != null))
            {
                resourceOwner.Claims.Remove(subjectClaim);
            }

            resourceOwner.Claims.Add(new Claim(SimpleIdentityServer.Core.Jwt.Constants.StandardResourceOwnerClaimNames.Subject, request.Login));
            resourceOwner.Claims.Add(new Claim(SimpleIdentityServer.Core.Jwt.Constants.StandardResourceOwnerClaimNames.UpdatedAt, DateTime.UtcNow.ToString()));
            var result = await _resourceOwnerRepository.UpdateAsync(resourceOwner);

            if (!result)
            {
                throw new IdentityServerManagerException(ErrorCodes.InternalErrorCode, ErrorDescriptions.TheClaimsCannotBeUpdated);
            }

            return(true);
        }
Exemple #9
0
        public Task <ResourceOwner> Execute(string subject)
        {
            if (string.IsNullOrWhiteSpace(subject))
            {
                throw new ArgumentNullException(nameof(subject));
            }


            return(_resourceOwnerRepository.GetAsync(subject));
        }
Exemple #10
0
        public async Task <bool> Execute(string subject, IEnumerable <ClaimAggregate> claims)
        {
            if (string.IsNullOrWhiteSpace(subject))
            {
                throw new ArgumentNullException(nameof(subject));
            }

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

            var resourceOwner = await _resourceOwnerRepository.GetAsync(subject);

            if (resourceOwner == null)
            {
                throw new IdentityServerException(Errors.ErrorCodes.InternalError, Errors.ErrorDescriptions.TheRoDoesntExist);
            }

            var supportedClaims = await _claimRepository.GetAllAsync();

            claims = claims.Where(c => supportedClaims.Any(sp => sp.Code == c.Code && !Jwt.Constants.NotEditableResourceOwnerClaimNames.Contains(c.Code)));
            var claimsToBeRemoved = resourceOwner.Claims
                                    .Where(cl => claims.Any(c => c.Code == cl.Type))
                                    .Select(cl => resourceOwner.Claims.IndexOf(cl))
                                    .OrderByDescending(p => p)
                                    .ToList();

            foreach (var index in claimsToBeRemoved)
            {
                resourceOwner.Claims.RemoveAt(index);
            }

            foreach (var claim in claims)
            {
                if (string.IsNullOrWhiteSpace(claim.Value))
                {
                    continue;
                }

                resourceOwner.Claims.Add(new Claim(claim.Code, claim.Value));
            }

            Claim updatedClaim;

            if (((updatedClaim = resourceOwner.Claims.FirstOrDefault(c => c.Type == Jwt.Constants.StandardResourceOwnerClaimNames.UpdatedAt)) != null))
            {
                resourceOwner.Claims.Remove(updatedClaim);
            }

            resourceOwner.Claims.Add(new Claim(Jwt.Constants.StandardResourceOwnerClaimNames.UpdatedAt, DateTime.UtcNow.ToString()));
            return(await _resourceOwnerRepository.UpdateAsync(resourceOwner));
        }
Exemple #11
0
        public Task <ResourceOwner> AuthenticateResourceOwnerAsync(string login, string password)
        {
            if (string.IsNullOrWhiteSpace(login))
            {
                throw new ArgumentNullException(nameof(login));
            }

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

            return(_resourceOwnerRepository.GetAsync(login, PasswordHelper.ComputeHash(password)));
        }
        public async Task <ResourceOwner> Execute(string externalSubject)
        {
            if (string.IsNullOrWhiteSpace(externalSubject))
            {
                throw new ArgumentNullException(nameof(externalSubject));
            }

            var profile = await _profileRepository.Get(externalSubject);

            if (profile == null)
            {
                return(null);
            }

            return(await _resourceOwnerRepository.GetAsync(profile.ResourceOwnerId));
        }
        public async Task <bool> Execute(string subject, string twoFactorAuth)
        {
            if (string.IsNullOrWhiteSpace(subject))
            {
                throw new ArgumentNullException(nameof(subject));
            }

            var resourceOwner = await _resourceOwnerRepository.GetAsync(subject);

            if (resourceOwner == null)
            {
                throw new IdentityServerException(Errors.ErrorCodes.InternalError, Errors.ErrorDescriptions.TheRoDoesntExist);
            }

            resourceOwner.TwoFactorAuthentication = twoFactorAuth;
            return(await _resourceOwnerRepository.UpdateAsync(resourceOwner));
        }
        public async Task <string> ExecuteAsync(string subject)
        {
            if (string.IsNullOrWhiteSpace(subject))
            {
                throw new ArgumentNullException(nameof(subject));
            }

            var resourceOwner = await _resourceOwnerRepository.GetAsync(subject);

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

            if (string.IsNullOrWhiteSpace(resourceOwner.TwoFactorAuthentication))
            {
                throw new IdentityServerException(
                          ErrorCodes.UnhandledExceptionCode,
                          ErrorDescriptions.TwoFactorAuthenticationIsNotEnabled);
            }

            var confirmationCode = new ConfirmationCode
            {
                Value     = await GetCode(),
                IssueAt   = DateTime.UtcNow,
                ExpiresIn = 300
            };

            var service = _twoFactorAuthenticationHandler.Get(resourceOwner.TwoFactorAuthentication);

            if (!resourceOwner.Claims.Any(c => c.Type == service.RequiredClaim))
            {
                throw new ClaimRequiredException(service.RequiredClaim);
            }

            if (!await _confirmationCodeStore.Add(confirmationCode))
            {
                throw new IdentityServerException(ErrorCodes.UnhandledExceptionCode, ErrorDescriptions.TheConfirmationCodeCannotBeSaved);
            }

            await _twoFactorAuthenticationHandler.SendCode(confirmationCode.Value, resourceOwner.TwoFactorAuthentication, resourceOwner);

            return(confirmationCode.Value);
        }
        /// <summary>
        /// Get the profiles linked to the user account.
        /// </summary>
        /// <param name="subject"></param>
        /// <returns></returns>
        public async Task <IEnumerable <ResourceOwnerProfile> > Execute(string subject)
        {
            if (string.IsNullOrWhiteSpace(subject))
            {
                throw new ArgumentNullException(nameof(subject));
            }


            var resourceOwner = await _resourceOwnerRepository.GetAsync(subject);

            if (resourceOwner == null)
            {
                throw new IdentityServerException(Errors.ErrorCodes.InternalError, Errors.ErrorDescriptions.TheResourceOwnerDoesntExist);
            }

            return(await _profileRepository.Search(new SearchProfileParameter
            {
                ResourceOwnerIds = new[] { subject }
            }));
        }
Exemple #16
0
        public async Task <ResourceOwner> Execute(string credentialType, string value)
        {
            if (string.IsNullOrWhiteSpace(credentialType))
            {
                throw new ArgumentNullException(nameof(credentialType));
            }

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

            var userCredential = await _resourceOwnerCredentialRepository.Get(credentialType, value).ConfigureAwait(false);

            if (userCredential == null)
            {
                return(null);
            }

            return(await _resourceOwnerRepository.GetAsync(userCredential.UserId).ConfigureAwait(false));
        }
Exemple #17
0
        public async Task <bool> Execute(string subject, string newPassword)
        {
            if (string.IsNullOrWhiteSpace(subject))
            {
                throw new ArgumentNullException(nameof(subject));
            }

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

            var resourceOwner = await _resourceOwnerRepository.GetAsync(subject);

            if (resourceOwner == null)
            {
                throw new IdentityServerException(Errors.ErrorCodes.InternalError, Errors.ErrorDescriptions.TheRoDoesntExist);
            }

            resourceOwner.Password = PasswordHelper.ComputeHash(newPassword);
            return(await _resourceOwnerRepository.UpdateAsync(resourceOwner));
        }
        public async Task <bool> Execute(UpdateResourceOwnerPasswordParameter request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            var resourceOwner = await _resourceOwnerRepository.GetAsync(request.Login);

            if (resourceOwner == null)
            {
                throw new IdentityServerManagerException(ErrorCodes.InvalidParameterCode, string.Format(ErrorDescriptions.TheResourceOwnerDoesntExist, request.Login));
            }

            resourceOwner.Password = PasswordHelper.ComputeHash(request.Password);
            var result = await _resourceOwnerRepository.UpdateAsync(resourceOwner);

            if (!result)
            {
                throw new IdentityServerManagerException(ErrorCodes.InternalErrorCode, ErrorDescriptions.ThePasswordCannotBeUpdated);
            }

            return(true);
        }
        /// <summary>
        /// This method is executed when the user confirm the consent
        /// 1). If there's already consent confirmed in the past by the resource owner
        /// 1).* then we generate an authorization code and redirects to the callback.
        /// 2). If there's no consent then we insert it and the authorization code is returned
        ///  2°.* to the callback url.
        /// </summary>
        /// <param name="authorizationParameter">Authorization code grant-type</param>
        /// <param name="claimsPrincipal">Resource owner's claims</param>
        /// <returns>Redirects the authorization code to the callback.</returns>
        public async Task <ActionResult> Execute(
            AuthorizationParameter authorizationParameter,
            ClaimsPrincipal claimsPrincipal, string issuerName)
        {
            if (authorizationParameter == null)
            {
                throw new ArgumentNullException(nameof(authorizationParameter));
            }

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

            var client = await _clientRepository.GetClientByIdAsync(authorizationParameter.ClientId);

            if (client == null)
            {
                throw new InvalidOperationException(string.Format("the client id {0} doesn't exist",
                                                                  authorizationParameter.ClientId));
            }

            var subject = claimsPrincipal.GetSubject();

            Common.Models.Consent assignedConsent = await _consentHelper.GetConfirmedConsentsAsync(subject, authorizationParameter);

            // Insert a new consent.
            if (assignedConsent == null)
            {
                var claimsParameter = authorizationParameter.Claims;
                if (claimsParameter.IsAnyIdentityTokenClaimParameter() ||
                    claimsParameter.IsAnyUserInfoClaimParameter())
                {
                    // A consent can be given to a set of claims
                    assignedConsent = new Common.Models.Consent
                    {
                        Id            = Guid.NewGuid().ToString(),
                        Client        = client,
                        ResourceOwner = await _resourceOwnerRepository.GetAsync(subject),
                        Claims        = claimsParameter.GetClaimNames()
                    };
                }
                else
                {
                    // A consent can be given to a set of scopes
                    assignedConsent = new Common.Models.Consent
                    {
                        Id            = Guid.NewGuid().ToString(),
                        Client        = client,
                        GrantedScopes = (await GetScopes(authorizationParameter.Scope)).ToList(),
                        ResourceOwner = await _resourceOwnerRepository.GetAsync(subject),
                    };
                }

                // A consent can be given to a set of claims
                await _consentRepository.InsertAsync(assignedConsent);

                _openidEventSource.GiveConsent(subject,
                                               authorizationParameter.ClientId,
                                               assignedConsent.Id);
            }

            var result = _actionResultFactory.CreateAnEmptyActionResultWithRedirectionToCallBackUrl();
            await _generateAuthorizationResponse.ExecuteAsync(result, authorizationParameter, claimsPrincipal, client, issuerName);

            // If redirect to the callback and the responde mode has not been set.
            if (result.Type == TypeActionResult.RedirectToCallBackUrl)
            {
                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);
        }
        public async Task <bool> Execute(string localSubject, string externalSubject, string issuer, bool force = false)
        {
            if (string.IsNullOrWhiteSpace(localSubject))
            {
                throw new ArgumentNullException(nameof(localSubject));
            }

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

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

            var resourceOwner = await _resourceOwnerRepository.GetAsync(localSubject);

            if (resourceOwner == null)
            {
                throw new IdentityServerException(Errors.ErrorCodes.InternalError, Errors.ErrorDescriptions.TheResourceOwnerDoesntExist);
            }

            var profile = await _profileRepository.Get(externalSubject);

            if (profile != null && profile.ResourceOwnerId != localSubject)
            {
                if (!force)
                {
                    throw new ProfileAssignedAnotherAccountException();
                }
                else
                {
                    await _profileRepository.Remove(new[] { externalSubject });

                    if (profile.ResourceOwnerId == profile.Subject)
                    {
                        await _resourceOwnerRepository.DeleteAsync(profile.ResourceOwnerId);
                    }

                    profile = null;
                }
            }

            if (profile != null)
            {
                throw new IdentityServerException(Errors.ErrorCodes.InternalError, Errors.ErrorDescriptions.TheProfileAlreadyLinked);
            }

            return(await _profileRepository.Add(new[]
            {
                new ResourceOwnerProfile
                {
                    ResourceOwnerId = localSubject,
                    Subject = externalSubject,
                    Issuer = issuer,
                    CreateDateTime = DateTime.UtcNow,
                    UpdateTime = DateTime.UtcNow
                }
            }));
        }
Exemple #21
0
        public async Task ExecuteAsync(ActionResult actionResult, AuthorizationParameter authorizationParameter, Client client, string issuerName, string authenticatedSubject)
        {
            if (actionResult == null || actionResult.RedirectInstruction == null)
            {
                throw new ArgumentNullException(nameof(actionResult));
            }
            ;
            if (authorizationParameter == null)
            {
                throw new ArgumentNullException(nameof(authorizationParameter));
            }

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

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

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

            _oauthEventSource.StartGeneratingAuthorizationResponseToClient(authorizationParameter.ClientId,
                                                                           authorizationParameter.ResponseType);
            var responses = _parameterParserHelper.ParseResponseTypes(authorizationParameter.ResponseType);
            var user      = await _resourceOwnerRepository.GetAsync(authenticatedSubject).ConfigureAwait(false);

            var claims         = user.Claims;
            var idTokenPayload = await GenerateIdTokenPayload(claims, authorizationParameter, issuerName).ConfigureAwait(false);

            var userInformationPayload = await GenerateUserInformationPayload(claims, authorizationParameter).ConfigureAwait(false);

            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,
                                                                                         issuerName, userInformationPayload, idTokenPayload);

                    newAccessTokenGranted = true;
                }

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

            if (responses.Contains(ResponseType.code)) // 2. Generate an authorization code.
            {
                var assignedConsent = await _consentHelper.GetConfirmedConsentsAsync(authenticatedSubject, authorizationParameter).ConfigureAwait(false);

                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);

                _oauthEventSource.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);

                _oauthEventSource.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;
            }

            _oauthEventSource.EndGeneratingAuthorizationResponseToClient(authorizationParameter.ClientId,
                                                                         JsonConvert.SerializeObject(actionResult.RedirectInstruction.Parameters));
        }
        public async Task <string> Execute(AddUserParameter addUserParameter, string issuer = null)
        {
            if (addUserParameter == null)
            {
                throw new ArgumentNullException(nameof(addUserParameter));
            }

            var subject = await _subjectBuilder.BuildSubject().ConfigureAwait(false);

            // 1. Check the resource owner already exists.
            if (await _resourceOwnerRepository.GetAsync(subject) != null)
            {
                throw new IdentityServerException(Errors.ErrorCodes.UnhandledExceptionCode, Errors.ErrorDescriptions.TheRoWithCredentialsAlreadyExists);
            }

            var newClaims = new List <Claim>
            {
                new Claim(Jwt.Constants.StandardResourceOwnerClaimNames.UpdatedAt, DateTime.UtcNow.ToString()),
                new Claim(Jwt.Constants.StandardResourceOwnerClaimNames.Subject, subject)
            };

            // 2. Populate the claims.
            var existedClaims = await _claimRepository.GetAllAsync().ConfigureAwait(false);

            if (addUserParameter.Claims != null)
            {
                foreach (var claim in addUserParameter.Claims)
                {
                    if (!newClaims.Any(nc => nc.Type == claim.Type) && existedClaims.Any(c => c.Code == claim.Type))
                    {
                        newClaims.Add(claim);
                    }
                }
            }

            var isFilterValid    = true;
            var userFilterResult = await _accountFilter.Check(newClaims).ConfigureAwait(false);

            if (!userFilterResult.IsValid)
            {
                isFilterValid = false;
                foreach (var ruleResult in userFilterResult.AccountFilterRules)
                {
                    if (!ruleResult.IsValid)
                    {
                        _openidEventSource.Failure($"the filter rule '{ruleResult.RuleName}' failed");
                        foreach (var errorMessage in ruleResult.ErrorMessages)
                        {
                            _openidEventSource.Failure(errorMessage);
                        }
                    }
                }
            }

            if (!isFilterValid)
            {
                throw new IdentityServerException(Errors.ErrorCodes.InternalError, Errors.ErrorDescriptions.TheUserIsNotAuthorized);
            }

            // 3. Add the scim resource.
            if (_userClaimsEnricherLst != null)
            {
                foreach (var userClaimsEnricher in _userClaimsEnricherLst)
                {
                    await userClaimsEnricher.Enrich(newClaims).ConfigureAwait(false);
                }
            }

            // 4. Add the resource owner.
            var newResourceOwner = new ResourceOwner
            {
                Id             = subject,
                Claims         = newClaims,
                CreateDateTime = DateTime.UtcNow,
                UpdateDateTime = DateTime.UtcNow,
                IsBlocked      = false
            };

            if (!await _resourceOwnerRepository.InsertAsync(newResourceOwner).ConfigureAwait(false))
            {
                throw new IdentityServerException(Errors.ErrorCodes.UnhandledExceptionCode, Errors.ErrorDescriptions.TheResourceOwnerCannotBeAdded);
            }

            // 5. Add credentials.
            if (addUserParameter.Credentials != null)
            {
                foreach (var c in addUserParameter.Credentials)
                {
                    c.UserId = subject;
                }

                await _addUserCredentialsOperation.Execute(addUserParameter.Credentials).ConfigureAwait(false);
            }

            // 6. Link to a profile.
            if (!string.IsNullOrWhiteSpace(issuer))
            {
                await _linkProfileAction.Execute(subject, addUserParameter.ExternalLogin, issuer).ConfigureAwait(false);
            }

            _openidEventSource.AddResourceOwner(newResourceOwner.Id);
            return(subject);
        }
 public override Task <ResourceOwner> GetResourceOwner(string login)
 {
     return(_resourceOwnerRepository.GetAsync(login));
 }