コード例 #1
0
        public async Task<CustomGrantValidationResult> ValidateAsync(ValidatedTokenRequest request)
        {
            var legacyAccountStoreType = request.Raw.Get("account_store");
            var id = request.Raw.Get("legacy_id");
            var secret = request.Raw.Get("legacy_secret");

            if (string.IsNullOrWhiteSpace(legacyAccountStoreType) ||
                string.IsNullOrWhiteSpace(id) ||
                string.IsNullOrWhiteSpace(secret))
            {
                Logger.Error("malformed request");
                return null;
            }

            var message = new SignInMessage { Tenant = legacyAccountStoreType };
            var context = new LocalAuthenticationContext
            {
                UserName = id, Password = secret,
                SignInMessage = message
            };
            await _users.AuthenticateLocalAsync(context);

            var result = context.AuthenticateResult;
            if (result.IsError)
            {
                Logger.Error("authentication failed");
                return new CustomGrantValidationResult("Authentication failed.");
            }

            return new CustomGrantValidationResult(
                result.User.GetSubjectId(),
                "custom",
                result.User.Claims);
        }
コード例 #2
0
        public TokenRequestValidationLog(ValidatedTokenRequest request)
        {
            const string scrubValue = "******";
            Raw = request.Raw.ToDictionary();

            if (Raw.ContainsKey(Constants.TokenRequest.Password))
            {
                Raw[Constants.TokenRequest.Password] = scrubValue;
            }

            if (request.Client != null)
            {
                ClientId = request.Client.ClientId;
                ClientName = request.Client.ClientName;
            }

            if (request.Scopes != null)
            {
                Scopes = request.Scopes.ToSpaceSeparatedString();
            }

            if (request.SignInMessage != null)
            {
                IdP = request.SignInMessage.IdP;
                Tenant = request.SignInMessage.Tenant;
                AuthenticationContextReferenceClasses = request.SignInMessage.AcrValues;
            }

            GrantType = request.GrantType;
            AuthorizationCode = request.AuthorizationCodeHandle;
            RefreshToken = request.RefreshTokenHandle;
            UserName = request.UserName;
        }
コード例 #3
0
        public async Task <CustomGrantValidationResult> ValidateAsync(ValidatedTokenRequest request)
        {
            var validator = _validators.FirstOrDefault(v => v.GrantType.Equals(request.GrantType, StringComparison.Ordinal));

            if (validator == null)
            {
                return(new CustomGrantValidationResult
                {
                    IsError = true,
                    Error = "No validator found for grant type"
                });
            }

            try
            {
                return(await validator.ValidateAsync(request));
            }
            catch (Exception e)
            {
                Logger.Error("Grant validation error:" + e.Message);
                return(new CustomGrantValidationResult
                {
                    IsError = true,
                    Error = "Grant validation error",
                });
            }
        }
コード例 #4
0
        public async Task<CustomGrantValidationResult> ValidateAsync(ValidatedTokenRequest request)
        {
            var validator = _validators.FirstOrDefault(v => v.GrantType.Equals(request.GrantType, StringComparison.Ordinal));

            if (validator == null)
            {
                return new CustomGrantValidationResult
                {
                    IsError = true,
                    Error = "No validator found for grant type"
                };
            }

            try
            {
                return await validator.ValidateAsync(request);
            }
            catch (Exception e)
            {
                Logger.Error("Grant validation error:" + e.Message);
                return new CustomGrantValidationResult
                {
                    IsError = true,
                    Error = "Grant validation error",
                };
            }
        }
コード例 #5
0
 /// <summary>
 /// Custom validation logic for the token request.
 /// </summary>
 /// <param name="request">The validated request.</param>
 /// <returns>
 /// The validation result
 /// </returns>
 public Task<TokenRequestValidationResult> ValidateTokenRequestAsync(ValidatedTokenRequest request)
 {
     return Task.FromResult(new TokenRequestValidationResult
     {
         IsError = false
     });
 }
コード例 #6
0
        public async Task Valid_Custom_Grant_Multiple_Validator()
        {
            var validator = new CustomGrantValidator(new List<ICustomGrantValidator> 
            { 
                new TestGrantValidator(), 
                new TestGrantValidator2() 
            });

            var request = new ValidatedTokenRequest
            {
                GrantType = "custom_grant"
            };

            var result = await validator.ValidateAsync(request);

            result.IsError.Should().BeFalse();
            result.Principal.Should().NotBeNull();
            result.Principal.GetSubjectId().Should().Be("bob");
            result.Principal.GetAuthenticationMethod().Should().Be("CustomGrant");

            request.GrantType = "custom_grant2";
            result = await validator.ValidateAsync(request);

            result.IsError.Should().BeFalse();
            result.Principal.Should().NotBeNull();
            result.Principal.GetSubjectId().Should().Be("alice");
            result.Principal.GetAuthenticationMethod().Should().Be("CustomGrant2");
        }
コード例 #7
0
        Task<CustomGrantValidationResult> ICustomGrantValidator.ValidateAsync(ValidatedTokenRequest request)
        {
            CustomGrantValidationResult grantResult = null;

            var param = request.Raw.Get("token");
            if (string.IsNullOrWhiteSpace(param))
            {
                grantResult = new CustomGrantValidationResult(Constants.TokenErrors.InvalidRequest);
            }

            var result = _validator.ValidateAccessTokenAsync(param).Result;
            if (result.IsError)
            {
                grantResult = new CustomGrantValidationResult(result.Error);
            }

            var subjectClaim = result.Claims.FirstOrDefault(x => x.Type == "sub");
            if(subjectClaim == null)
            {
                grantResult = new CustomGrantValidationResult(Constants.TokenErrors.InvalidRequest);
            }

            if (grantResult == null)
            {
                grantResult = new CustomGrantValidationResult(subjectClaim.Value, "access_token");
            }

            return Task.FromResult(grantResult);
        }
コード例 #8
0
        public Task<TokenResponse> GenerateAsync(ValidatedTokenRequest request, TokenResponse response)
        {
            response.Custom.Add("custom_field", "custom data");
            response.Custom.Add("custom_complex_field", new ResponsePoco { SomeString = "foo", SomeInt = 42 });


            return Task.FromResult(response);
        }
コード例 #9
0
        Task<CustomGrantValidationResult> ICustomGrantValidator.ValidateAsync(ValidatedTokenRequest request)
        {
            var param = request.Raw.Get("some_custom_parameter");
            if (string.IsNullOrWhiteSpace(param))
            {
                return Task.FromResult<CustomGrantValidationResult>(
                    new CustomGrantValidationResult("Missing parameters."));
            }

            return Task.FromResult(new CustomGrantValidationResult("bob", "customGrant"));
        }
コード例 #10
0
        private async Task<TokenResponse> ProcessAuthorizationCodeRequestAsync(ValidatedTokenRequest request)
        {
            Logger.Info("Processing authorization code request");

            //////////////////////////
            // access token
            /////////////////////////
            var accessToken = await CreateAccessTokenAsync(request);
            var response = new TokenResponse
            {
                AccessToken = accessToken.Item1,
                AccessTokenLifetime = request.Client.AccessTokenLifetime
            };

            if (request.RequestedTokenType == RequestedTokenTypes.PoP)
            {
                response.TokenType = Constants.ResponseTokenTypes.PoP;
                response.Algorithm = request.ProofKeyAlgorithm;
            }

            //////////////////////////
            // refresh token
            /////////////////////////
            if (accessToken.Item2.IsPresent())
            {
                response.RefreshToken = accessToken.Item2;
            }

            //////////////////////////
            // id token
            /////////////////////////
            if (request.AuthorizationCode.IsOpenId)
            {
                var tokenRequest = new TokenCreationRequest
                {
                    Subject = request.AuthorizationCode.Subject,
                    Client = request.AuthorizationCode.Client,
                    Scopes = request.AuthorizationCode.RequestedScopes,
                    Nonce = request.AuthorizationCode.Nonce,

                    ValidatedRequest = request
                };

                var idToken = await _tokenService.CreateIdentityTokenAsync(tokenRequest);
                var jwt = await _tokenService.CreateSecurityTokenAsync(idToken);
                response.IdentityToken = jwt;
            }

            return response;
        }
コード例 #11
0
        public Task<CustomGrantValidationResult> ValidateAsync(ValidatedTokenRequest request)
        {
            var credential = request.Raw.Get("custom_credential");

            if (credential != null)
            {
                // valid credential
                return Task.FromResult(new CustomGrantValidationResult("818727", "custom"));
            }
            else
            {
                // custom error message
                return Task.FromResult(new CustomGrantValidationResult("invalid custom credential"));
            }
        }
コード例 #12
0
        public async Task<TokenResponse> ProcessAsync(ValidatedTokenRequest request)
        {
            Logger.Info("Creating token response");

            if (request.GrantType == Constants.GrantTypes.AuthorizationCode)
            {
                return await ProcessAuthorizationCodeRequestAsync(request);
            }

            if (request.GrantType == Constants.GrantTypes.RefreshToken)
            {
                return await ProcessRefreshTokenRequestAsync(request);
            }

            return await ProcessTokenRequestAsync(request);
        }
コード例 #13
0
        public async Task <CustomGrantValidationResult> ValidateAsync(ValidatedTokenRequest request)
        {
            var validator = _validators.FirstOrDefault(v => v.GrantType.Equals(request.GrantType, StringComparison.Ordinal));

            if (validator != null)
            {
                return(await validator.ValidateAsync(request));
            }
            else
            {
                return(new CustomGrantValidationResult
                {
                    IsError = true,
                    ErrorDescription = "No validator found for grant type"
                });
            }
        }
コード例 #14
0
        public async Task<CustomGrantValidationResult> ValidateAsync(ValidatedTokenRequest request)
        {
            var validator = _validators.FirstOrDefault(v => v.GrantType.Equals(request.GrantType, StringComparison.Ordinal));

            if (validator != null)
            {
                return await validator.ValidateAsync(request);
            }
            else
            {
                return new CustomGrantValidationResult 
                { 
                    IsError = true, 
                    ErrorDescription = "No validator found for grant type" 
                };
            }
        }
コード例 #15
0
        public async Task Valid_Custom_Grant_Validator_Throws_Exception()
        {
            var validatorThrowingException = new Mock<ICustomGrantValidator>();
            validatorThrowingException.Setup(y => y.ValidateAsync(It.IsAny<ValidatedTokenRequest>())).Throws(new Exception("Random validation error"));
            validatorThrowingException.Setup(y => y.GrantType).Returns("custom_grant");
            var validator = new CustomGrantValidator(new[] { validatorThrowingException.Object});
            var request = new ValidatedTokenRequest
            {
                GrantType = validator.GetAvailableGrantTypes().Single()
            };

            var result = await validator.ValidateAsync(request);

            result.IsError.Should().BeTrue();
            result.Error.Should().Be("Grant validation error");
            result.Principal.Should().BeNull();
            
        }
コード例 #16
0
        public async Task<TokenResponse> ProcessAsync(ValidatedTokenRequest request)
        {
            Logger.Info("Creating token response");

            TokenResponse response;

            if (request.GrantType == Constants.GrantTypes.AuthorizationCode)
            {
                response = await ProcessAuthorizationCodeRequestAsync(request);
            }
            else if (request.GrantType == Constants.GrantTypes.RefreshToken)
            {
                response = await ProcessRefreshTokenRequestAsync(request);
            }
            else
            {
                response = await ProcessTokenRequestAsync(request);
            }

            return await _customResponseGenerator.GenerateAsync(request, response);
        }
コード例 #17
0
 /// <summary>
 /// Custom response generation
 /// </summary>
 /// <param name="request">The validated request.</param>
 /// <param name="response">The standard token response.</param>
 /// <returns>The custom token response.</returns>
 public Task<TokenResponse> GenerateAsync(ValidatedTokenRequest request, TokenResponse response)
 {
     return Task.FromResult(response);
 }
コード例 #18
0
        public async Task Unknown_Custom_Grant_Multiple_Validator()
        {
            var validator = new CustomGrantValidator(new List<ICustomGrantValidator> 
            { 
                new TestGrantValidator(), 
                new TestGrantValidator2() 
            });

            var request = new ValidatedTokenRequest
            {
                GrantType = "unknown"
            };

            var result = await validator.ValidateAsync(request);

            result.IsError.Should().BeTrue();
        }
コード例 #19
0
        public Task<TokenResponse> GenerateAsync(ValidatedTokenRequest request, TokenResponse response)
        {
            response.Custom.Add("custom_field", "custom data");

            return Task.FromResult(response);
        }
コード例 #20
0
        public async Task Empty_Validator_List()
        {
            var validator = new CustomGrantValidator(new List<ICustomGrantValidator>());

            var request = new ValidatedTokenRequest
            {
                GrantType = "something"
            };

            var result = await validator.ValidateAsync(request);

            result.IsError.Should().BeTrue();
        }
コード例 #21
0
        private async Task<Tuple<string, string>> CreateAccessTokenAsync(ValidatedTokenRequest request)
        {
            TokenCreationRequest tokenRequest;
            bool createRefreshToken;

            if (request.AuthorizationCode != null)
            {
                createRefreshToken = request.AuthorizationCode.RequestedScopes.Select(s => s.Name).Contains(Constants.StandardScopes.OfflineAccess);
                
                tokenRequest = new TokenCreationRequest
                {
                    Subject = request.AuthorizationCode.Subject,
                    Client = request.AuthorizationCode.Client,
                    Scopes = request.AuthorizationCode.RequestedScopes,
                    ValidatedRequest = request
                };
            }
            else
            {
                createRefreshToken = request.ValidatedScopes.ContainsOfflineAccessScope;

                tokenRequest = new TokenCreationRequest
                {
                    Subject = request.Subject,
                    Client = request.Client,
                    Scopes = request.ValidatedScopes.GrantedScopes,
                    ValidatedRequest = request
                };
            }

            Token accessToken = await _tokenService.CreateAccessTokenAsync(tokenRequest);

            string refreshToken = "";
            if (createRefreshToken)
            {
                refreshToken = await _refreshTokenService.CreateRefreshTokenAsync(tokenRequest.Subject, accessToken, request.Client);
            }

            var securityToken = await _tokenService.CreateSecurityTokenAsync(accessToken);
            return Tuple.Create(securityToken, refreshToken);
        }
 private static ValidatedTokenRequest Request(string assertion)
 {
     var request = new ValidatedTokenRequest()
     {
         Raw = new NameValueCollection()
     };
     request.Raw["assertion"] = assertion;
     return request;
 }
コード例 #23
0
        private async Task<TokenResponse> ProcessTokenRequestAsync(ValidatedTokenRequest request)
        {
            Logger.Info("Processing token request");

            var accessToken = await CreateAccessTokenAsync(request);
            var response = new TokenResponse
            {
                AccessToken = accessToken.Item1,
                AccessTokenLifetime = request.Client.AccessTokenLifetime
            };

            if (accessToken.Item2.IsPresent())
            {
                response.RefreshToken = accessToken.Item2;
            }

            return response;
        }
コード例 #24
0
        private async Task<TokenResponse> ProcessRefreshTokenRequestAsync(ValidatedTokenRequest request)
        {
            Logger.Info("Processing refresh token request");

            var oldAccessToken = request.RefreshToken.AccessToken;
            string accessTokenString;
            
            if (request.Client.UpdateAccessTokenClaimsOnRefresh)
            {
                var subject = request.RefreshToken.GetOriginalSubject();

                var creationRequest = new TokenCreationRequest
                {
                    Client = request.Client,
                    Subject = subject,
                    ValidatedRequest = request,
                    Scopes = await _scopes.FindScopesAsync(oldAccessToken.Scopes)
                };

                var newAccessToken = await _tokenService.CreateAccessTokenAsync(creationRequest);
                accessTokenString = await _tokenService.CreateSecurityTokenAsync(newAccessToken);
            }
            else
            {
                oldAccessToken.CreationTime = DateTimeOffsetHelper.UtcNow;
                oldAccessToken.Lifetime = request.Client.AccessTokenLifetime;

                accessTokenString = await _tokenService.CreateSecurityTokenAsync(oldAccessToken);
            }

            var handle = await _refreshTokenService.UpdateRefreshTokenAsync(request.RefreshTokenHandle, request.RefreshToken, request.Client);

            return new TokenResponse
                {
                    AccessToken = accessTokenString,
                    AccessTokenLifetime = request.Client.AccessTokenLifetime,
                    RefreshToken = handle
                };
        }
        public void ValidateAsync_Given_Missing_Assertion_Should_Throw_ArgumentNullException()
        {
            // Given
            var request = new ValidatedTokenRequest();

            // When, Then
            Assert.Throws(Is.TypeOf<ArgumentNullException>().And.Message.Contains("SAML response not found"), async () => await underTest.ValidateAsync(request));
        }
コード例 #26
0
        public async Task<TokenRequestValidationResult> ValidateRequestAsync(NameValueCollection parameters, Client client)
        {
            Logger.Info("Start token request validation");

            _validatedRequest = new ValidatedTokenRequest();

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

            if (parameters == null)
            {
                throw new ArgumentNullException("parameters");
            }

            _validatedRequest.Raw = parameters;
            _validatedRequest.Client = client;
            _validatedRequest.Options = _options;

            /////////////////////////////////////////////
            // check grant type
            /////////////////////////////////////////////
            var grantType = parameters.Get(Constants.TokenRequest.GrantType);
            if (grantType.IsMissing())
            {
                LogError("Grant type is missing.");
                return Invalid(Constants.TokenErrors.UnsupportedGrantType);
            }

            if (grantType.Length > _options.InputLengthRestrictions.GrantType)
            {
                LogError("Grant type is too long.");
                return Invalid(Constants.TokenErrors.UnsupportedGrantType);
            }

            _validatedRequest.GrantType = grantType;

            // standard grant types
            switch (grantType)
            {
                case Constants.GrantTypes.AuthorizationCode:
                    return await RunValidationAsync(ValidateAuthorizationCodeRequestAsync, parameters);
                case Constants.GrantTypes.ClientCredentials:
                    return await RunValidationAsync(ValidateClientCredentialsRequestAsync, parameters);
                case Constants.GrantTypes.Password:
                    return await RunValidationAsync(ValidateResourceOwnerCredentialRequestAsync, parameters);
                case Constants.GrantTypes.RefreshToken:
                    return await RunValidationAsync(ValidateRefreshTokenRequestAsync, parameters);
            }

            // custom grant type
            var result = await RunValidationAsync(ValidateCustomGrantRequestAsync, parameters);

            if (result.IsError)
            {
                if (result.Error.IsPresent())
                {
                    return result;
                }

                LogError("Unsupported grant_type: " + grantType);
                return Invalid(Constants.TokenErrors.UnsupportedGrantType);
            }

            return result;
        }
コード例 #27
0
        private async Task<TokenResponse> ProcessRefreshTokenRequestAsync(ValidatedTokenRequest request)
        {
            Logger.Info("Processing refresh token request");

            var oldAccessToken = request.RefreshToken.AccessToken;
            string accessTokenString;
            
            // if pop request, claims must be updated because we need a fresh proof token
            if (request.Client.UpdateAccessTokenClaimsOnRefresh || request.RequestedTokenType == RequestedTokenTypes.PoP)
            {
                var subject = request.RefreshToken.GetOriginalSubject();

                var creationRequest = new TokenCreationRequest
                {
                    Client = request.Client,
                    Subject = subject,
                    ValidatedRequest = request,
                    Scopes = await _scopes.FindScopesAsync(oldAccessToken.Scopes),
                };

                // if pop request, embed proof token
                if (request.RequestedTokenType == RequestedTokenTypes.PoP)
                {
                    creationRequest.ProofKey = GetProofKey(request);
                }

                var newAccessToken = await _tokenService.CreateAccessTokenAsync(creationRequest);
                accessTokenString = await _tokenService.CreateSecurityTokenAsync(newAccessToken);
            }
            else
            {
                var copy = new Token(oldAccessToken);
                copy.CreationTime = DateTimeOffsetHelper.UtcNow;
                copy.Lifetime = request.Client.AccessTokenLifetime;

                accessTokenString = await _tokenService.CreateSecurityTokenAsync(copy);
            }

            var handle = await _refreshTokenService.UpdateRefreshTokenAsync(request.RefreshTokenHandle, request.RefreshToken, request.Client);

            var response = new TokenResponse
            {
                AccessToken = accessTokenString,
                AccessTokenLifetime = request.Client.AccessTokenLifetime,
                RefreshToken = handle
            };

            if (request.RequestedTokenType == RequestedTokenTypes.PoP)
            {
                response.TokenType = Constants.ResponseTokenTypes.PoP;
                response.Algorithm = request.ProofKeyAlgorithm;
            }

            return response;
        }
コード例 #28
0
 private string GetProofKey(ValidatedTokenRequest request)
 {
     // for now we only support client generated proof keys
     return request.ProofKey;
 }
コード例 #29
0
        public async Task <TokenRequestValidationResult> ValidateRequestAsync(NameValueCollection parameters, Client client)
        {
            Logger.Info("Start token request validation");

            _validatedRequest = new ValidatedTokenRequest();

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

            if (parameters == null)
            {
                throw new ArgumentNullException("parameters");
            }

            _validatedRequest.Raw     = parameters;
            _validatedRequest.Client  = client;
            _validatedRequest.Options = _options;

            /////////////////////////////////////////////
            // check grant type
            /////////////////////////////////////////////
            var grantType = parameters.Get(Constants.TokenRequest.GrantType);

            if (grantType.IsMissing())
            {
                LogError("Grant type is missing.");
                return(Invalid(Constants.TokenErrors.UnsupportedGrantType));
            }

            if (grantType.Length > _options.InputLengthRestrictions.GrantType)
            {
                LogError("Grant type is too long.");
                return(Invalid(Constants.TokenErrors.UnsupportedGrantType));
            }

            _validatedRequest.GrantType = grantType;

            // standard grant types
            switch (grantType)
            {
            case Constants.GrantTypes.AuthorizationCode:
                return(await RunValidationAsync(ValidateAuthorizationCodeRequestAsync, parameters));

            case Constants.GrantTypes.ClientCredentials:
                return(await RunValidationAsync(ValidateClientCredentialsRequestAsync, parameters));

            case Constants.GrantTypes.Password:
                return(await RunValidationAsync(ValidateResourceOwnerCredentialRequestAsync, parameters));

            case Constants.GrantTypes.RefreshToken:
                return(await RunValidationAsync(ValidateRefreshTokenRequestAsync, parameters));
            }

            // custom grant type
            var result = await RunValidationAsync(ValidateCustomGrantRequestAsync, parameters);

            if (result.IsError)
            {
                if (result.Error.IsPresent())
                {
                    return(result);
                }

                LogError("Unsupported grant_type: " + grantType);
                return(Invalid(Constants.TokenErrors.UnsupportedGrantType));
            }

            return(result);
        }
コード例 #30
0
 public Task<CustomGrantValidationResult> ValidateAsync(ValidatedTokenRequest request)
 {
     return Task.FromResult(new CustomGrantValidationResult("alice", "CustomGrant2"));
 }
コード例 #31
0
 public Task<CustomGrantValidationResult> ValidateAsync(ValidatedTokenRequest request)
 {
     return Task.FromResult<CustomGrantValidationResult>(null);
 }