Beispiel #1
0
        public async Task When_Pass_Null_Parameters_Then_Exceptions_Are_Thrown()
        {
            // ARRANGE
            InitializeFakeObjects();

            // ACTS & ASSERTS
            await Assert.ThrowsAsync <ArgumentNullException>(() => _authenticateResourceOwnerService.AuthenticateResourceOwnerAsync(null, null));

            await Assert.ThrowsAsync <ArgumentNullException>(() => _authenticateResourceOwnerService.AuthenticateResourceOwnerAsync("login", null));
        }
        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(_authenticateResourceOwnerService.AuthenticateResourceOwnerAsync(subject));
        }
Beispiel #3
0
        public async Task <ExternalOpenIdAuthenticationResult> Execute(
            List <Claim> claims,
            AuthorizationParameter authorizationParameter,
            string code)
        {
            // 1. Check parameters.
            if (claims == null || !claims.Any())
            {
                throw new ArgumentNullException(nameof(claims));
            }

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

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

            // 2. Subject cannot be extracted.
            var subject = claims.GetSubject();

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

            // 3. Create the resource owner if needed.
            var resourceOwner = await _authenticateResourceOwnerService.AuthenticateResourceOwnerAsync(subject);

            if (resourceOwner == null)
            {
                var standardClaims = await _claimRepository.GetAllAsync();

                resourceOwner = new ResourceOwner
                {
                    Id                      = subject,
                    IsLocalAccount          = false,
                    TwoFactorAuthentication = TwoFactorAuthentications.NONE,
                    Claims                  = claims.Where(c => standardClaims.Any(sc => sc == c.Type)).ToList()
                };
                if (!resourceOwner.Claims.Any(c => c.Type == Jwt.Constants.StandardResourceOwnerClaimNames.Subject))
                {
                    resourceOwner.Claims.Add(new Claim(Jwt.Constants.StandardResourceOwnerClaimNames.Subject, subject));
                }

                await _resourceOwnerRepository.InsertAsync(resourceOwner);
            }
            return(new ExternalOpenIdAuthenticationResult
            {
                ActionResult = await _authenticateHelper.ProcessRedirection(authorizationParameter,
                                                                            code,
                                                                            "subject",
                                                                            claims),
                Claims = resourceOwner.Claims
            });
        }
        public async Task <bool> Execute(AddUserParameter addUserParameter)
        {
            if (addUserParameter == null)
            {
                throw new ArgumentNullException(nameof(addUserParameter));
            }

            if (string.IsNullOrEmpty(addUserParameter.Login))
            {
                throw new ArgumentNullException(nameof(addUserParameter.Login));
            }

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

            if (await _authenticateResourceOwnerService.AuthenticateResourceOwnerAsync(addUserParameter.Login,
                                                                                       addUserParameter.Password) != 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, addUserParameter.Login)
            };
            var newResourceOwner = new ResourceOwner
            {
                Id     = addUserParameter.Login,
                Claims = newClaims,
                TwoFactorAuthentication = TwoFactorAuthentications.NONE,
                IsLocalAccount          = true,
                Password = _authenticateResourceOwnerService.GetHashedPassword(addUserParameter.Password)
            };
            var claims = (await _claimRepository.GetAllAsync()).Select(c => c.Code);

            if (addUserParameter.Claims != null)
            {
                foreach (var claim in addUserParameter.Claims.Where(c => claims.Contains(c.Type)))
                {
                    newResourceOwner.Claims.Add(claim);
                }
            }

            if (!newResourceOwner.Claims.Any(c => c.Type == Jwt.Constants.StandardResourceOwnerClaimNames.Subject))
            {
                newResourceOwner.Claims.Add(new Claim(Jwt.Constants.StandardResourceOwnerClaimNames.Subject, addUserParameter.Login));
            }

            await _resourceOwnerRepository.InsertAsync(newResourceOwner);

            return(true);
        }
        public async Task 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);
            }

            var result = await _authenticateResourceOwnerService.AuthenticateResourceOwnerAsync(subject);

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

            if (result.IsLocalAccount)
            {
                throw new IdentityServerException(
                          Errors.ErrorCodes.UnhandledExceptionCode,
                          Errors.ErrorDescriptions.TheAccountHasAlreadyBeenActivated);
            }

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

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

            await _resourceOwnerRepository.UpdateAsync(result);
        }
Beispiel #6
0
        public async Task <ResourceOwner> Execute(LocalAuthenticationParameter localAuthenticationParameter)
        {
            if (localAuthenticationParameter == null)
            {
                throw new ArgumentNullException("localAuthenticationParameter");
            }

            var record = await _authenticateResourceOwnerService.AuthenticateResourceOwnerAsync(localAuthenticationParameter.UserName,
                                                                                                localAuthenticationParameter.Password);

            if (record == null)
            {
                throw new IdentityServerAuthenticationException(ErrorDescriptions.TheResourceOwnerCredentialsAreNotCorrect);
            }

            return(record);
        }
        public async Task <string> ExecuteAsync(string subject)
        {
            if (string.IsNullOrWhiteSpace(subject))
            {
                throw new ArgumentNullException(nameof(subject));
            }

            var resourceOwner = await _authenticateResourceOwnerService.AuthenticateResourceOwnerAsync(subject);

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

            if (resourceOwner.TwoFactorAuthentication == TwoFactorAuthentications.NONE)
            {
                throw new IdentityServerException(
                          ErrorCodes.UnhandledExceptionCode,
                          ErrorDescriptions.TwoFactorAuthenticationIsNotEnabled);
            }

            var confirmationCode = new ConfirmationCode
            {
                Code           = await GetCode(),
                CreateDateTime = DateTime.UtcNow,
                ExpiresIn      = 300,
                IsConfirmed    = false
            };

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

            await _twoFactorAuthenticationHandler.SendCode(confirmationCode.Code, (int)resourceOwner.TwoFactorAuthentication, resourceOwner);

            return(confirmationCode.Code);
        }
        public async Task <bool> Execute(UpdateUserParameter updateUserParameter)
        {
            if (updateUserParameter == null)
            {
                throw new ArgumentNullException(nameof(updateUserParameter));
            }

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

            var resourceOwner = await _authenticateResourceOwnerService.AuthenticateResourceOwnerAsync(updateUserParameter.Login);

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

            resourceOwner.TwoFactorAuthentication = updateUserParameter.TwoFactorAuthentication;
            if (!string.IsNullOrWhiteSpace(updateUserParameter.Password))
            {
                resourceOwner.Password = _authenticateResourceOwnerService.GetHashedPassword(updateUserParameter.Password);
            }

            resourceOwner.Claims = updateUserParameter.Claims;
            if (resourceOwner.Claims != null)
            {
                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));
        }
        public async Task Execute(AddUserParameter addUserParameter)
        {
            if (addUserParameter == null)
            {
                throw new ArgumentNullException(nameof(addUserParameter));
            }

            if (string.IsNullOrEmpty(addUserParameter.Login))
            {
                throw new ArgumentNullException(nameof(addUserParameter.Login));
            }

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

            if (await _authenticateResourceOwnerService.AuthenticateResourceOwnerAsync(addUserParameter.Login,
                                                                                       addUserParameter.Password) != null)
            {
                throw new IdentityServerException(
                          Errors.ErrorCodes.UnhandledExceptionCode,
                          Errors.ErrorDescriptions.TheRoWithCredentialsAlreadyExists);
            }

            var claims = new List <Claim>
            {
                new Claim(Jwt.Constants.StandardResourceOwnerClaimNames.UpdatedAt, DateTime.UtcNow.ToString()),
                new Claim(Jwt.Constants.StandardResourceOwnerClaimNames.Subject, addUserParameter.Login)
            };
            var newResourceOwner = new ResourceOwner
            {
                Id     = addUserParameter.Login,
                Claims = claims,
                TwoFactorAuthentication = TwoFactorAuthentications.NONE,
                IsLocalAccount          = true,
                Password = _authenticateResourceOwnerService.GetHashedPassword(addUserParameter.Password)
            };
            await _resourceOwnerRepository.InsertAsync(newResourceOwner);
        }
        /// <summary>
        /// Authenticate local user account.
        /// Exceptions :
        /// Throw the exception <see cref="IdentityServerAuthenticationException "/> if the user cannot be authenticated
        /// </summary>
        /// <param name="localAuthenticationParameter">User's credentials</param>
        /// <param name="authorizationParameter">Authorization parameters</param>
        /// <param name="code">Encrypted & signed authorization parameters</param>
        /// <param name="claims">Returned the claims of the authenticated user</param>
        /// <returns>Consent screen or redirect to the Index page.</returns>
        public async Task <LocalOpenIdAuthenticationResult> Execute(
            LocalAuthenticationParameter localAuthenticationParameter,
            AuthorizationParameter authorizationParameter,
            string code)
        {
            if (localAuthenticationParameter == null)
            {
                throw new ArgumentNullException(nameof(localAuthenticationParameter));
            }

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

            var resourceOwner = await _authenticateResourceOwnerService.AuthenticateResourceOwnerAsync(localAuthenticationParameter.UserName,
                                                                                                       localAuthenticationParameter.Password);

            if (resourceOwner == null)
            {
                throw new IdentityServerAuthenticationException("the resource owner credentials are not correct");
            }

            var claims = resourceOwner.Claims == null ? new List <Claim>() : resourceOwner.Claims.ToList();

            claims.Add(new Claim(ClaimTypes.AuthenticationInstant,
                                 DateTimeOffset.UtcNow.ConvertToUnixTimestamp().ToString(CultureInfo.InvariantCulture),
                                 ClaimValueTypes.Integer));
            return(new LocalOpenIdAuthenticationResult
            {
                ActionResult = await _authenticateHelper.ProcessRedirection(authorizationParameter,
                                                                            code,
                                                                            resourceOwner.Id,
                                                                            claims),
                Claims = claims
            });
        }
Beispiel #11
0
        /// <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)
        {
            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
                    {
                        Client        = client,
                        ResourceOwner = await _authenticateResourceOwnerService.AuthenticateResourceOwnerAsync(subject),
                        Claims        = claimsParameter.GetClaimNames()
                    };
                }
                else
                {
                    // A consent can be given to a set of scopes
                    assignedConsent = new Common.Models.Consent
                    {
                        Client        = client,
                        GrantedScopes = (await GetScopes(authorizationParameter.Scope)).ToList(),
                        ResourceOwner = await _authenticateResourceOwnerService.AuthenticateResourceOwnerAsync(subject),
                    };
                }

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

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

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

            // 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 <IEnumerable <Claim> > Execute(ClaimsPrincipal claimsPrincipal)
        {
            // 1. Check parameters.
            if (claimsPrincipal == null)
            {
                throw new ArgumentNullException(nameof(claimsPrincipal));
            }

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

            // 3. Check the subject exists.
            var subject = claimsPrincipal.GetSubject();

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

            // 4. If a user already exists with the same subject then ignore.
            var resourceOwner = await _authenticateResourceOwnerService.AuthenticateResourceOwnerAsync(subject);

            if (resourceOwner != null)
            {
                return(resourceOwner.Claims);
            }

            // 5. Insert the resource owner.
            var clearPassword = Guid.NewGuid().ToString();

            resourceOwner = new ResourceOwner
            {
                Id                      = subject,
                IsLocalAccount          = false,
                TwoFactorAuthentication = TwoFactorAuthentications.NONE,
                Claims                  = new List <Claim>(),
                Password                = _authenticateResourceOwnerService.GetHashedPassword(clearPassword)
            };
            var claims = await _claimRepository.GetAllAsync();

            foreach (var claim in claimsPrincipal.Claims.Where(c => claims.Contains(c.Type)))
            {
                resourceOwner.Claims.Add(claim);
            }

            if (!resourceOwner.Claims.Any(c => c.Type == Jwt.Constants.StandardResourceOwnerClaimNames.Subject))
            {
                resourceOwner.Claims.Add(new Claim(Jwt.Constants.StandardResourceOwnerClaimNames.Subject, subject));
            }

            await _resourceOwnerRepository.InsertAsync(resourceOwner);

            return(resourceOwner.Claims);
        }
Beispiel #13
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.ClientId, allowedTokenScopes, payload, payload);

                await _grantedTokenRepository.InsertAsync(generatedToken);

                // Fill-in the id-token
                if (generatedToken.IdTokenPayLoad != null)
                {
                    generatedToken.IdToken = await _clientHelper.GenerateIdTokenAsync(client, generatedToken.IdTokenPayLoad);
                }

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

            return(generatedToken);
        }