public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            var userToken = context.Request.Raw.Get("token");

            if (string.IsNullOrEmpty(userToken))
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
                return;
            }

            var result = await _validator.ValidateAccessTokenAsync(userToken);

            if (result.IsError)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
                return;
            }

            var sub = context.Request.Raw.Get("sub");

            if (!string.IsNullOrEmpty(sub))
            {
                context.Result = new GrantValidationResult(sub, "delegation");
            }
            else
            {
                context.Result = new GrantValidationResult();
            }

            return;
        }
Exemple #2
0
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            // Get current reference token from request
            var userToken = context.Request.Raw.Get("reference_token");

            if (string.IsNullOrEmpty(userToken))
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
                return;
            }

            // Validate reference token
            var result = await _validator.ValidateAccessTokenAsync(userToken);

            if (result.IsError)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
                return;
            }

            // Generate the JWT as if it was for the reference token's client
            context.Request.Client          = result.Client;
            context.Request.AccessTokenType = AccessTokenType.Jwt;

            var sub = result.Claims.FirstOrDefault(c => c.Type == "sub").Value;

            context.Result = new GrantValidationResult(sub, GrantType, result.Claims);
            return;
        }
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            // It's the job of the extension grant validator to handle that request by validating the incoming token,
            // and returning a result that represents the new token
            var userToken = context.Request.Raw.Get("token");

            if (string.IsNullOrEmpty(userToken))
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
                return;
            }

            var result = await _validator.ValidateAccessTokenAsync(userToken);

            if (result.IsError)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
                return;
            }

            // get user's identity
            var sub = result.Claims.FirstOrDefault(c => c.Type == "sub").Value;

            context.Result = new GrantValidationResult(sub, "delegation");
            return;
        }
Exemple #4
0
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            var requestedGrant = context.Request.Raw.Get("grant_type");

            if (string.IsNullOrWhiteSpace(requestedGrant) || requestedGrant != GrantType)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant,
                                                           "Invalid grant.");
                return;
            }

            var subjectToken = context.Request.Raw.Get("subject_token");

            if (string.IsNullOrWhiteSpace(subjectToken))
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest,
                                                           "Subject token missing.");
                return;
            }

            var subjectTokenType = context.Request.Raw.Get("subject_token_type");

            if (string.IsNullOrWhiteSpace(subjectTokenType))
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest,
                                                           "Subject token type missing.");
                return;
            }

            // use the subject token type to know how to validate it.  Must be
            // an access token in our case
            if (subjectTokenType != _accessTokenType)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest,
                                                           "Subject token type invalid.");
                return;
            }

            var result = await _validator.ValidateAccessTokenAsync(subjectToken);

            if (result.IsError)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant,
                                                           "Subject token invalid.");
                return;
            }

            // get the subject from the access token
            var subjectClaim = result.Claims.FirstOrDefault(c => c.Type == "sub");

            if (subjectClaim == null)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest,
                                                           "Subject token must contain sub value.");
                return;
            }

            context.Result = new GrantValidationResult(subjectClaim.Value, "access_token", result.Claims);
            return;
        }
    public async Task ValidateAsync(ExtensionGrantValidationContext context)
    {
        var userToken = context.Request.Raw.Get("accessToken");
        var tenant    = context.Request.Raw.Get("chosenTenant");

        if (string.IsNullOrEmpty(userToken))
        {
            context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
            return;
        }

        var result = await _tokenValidator.ValidateAccessTokenAsync(userToken);

        if (result.IsError)
        {
            context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
            return;
        }
        // logic to validate the user and tenant
        // ..
        // issue a new claimsprincipal to reflect the new "persona"
        var claims = result.Claims.ToList();

        claims.RemoveAll(p => p.Type == "role");
        claims.RemoveAll(p => p.Type == "chosentenant");
        claims.Add(new Claim("chosentenant", tenant));
        var identity  = new ClaimsIdentity(claims);
        var principal = new ClaimsPrincipal(identity);

        context.Result = new GrantValidationResult(principal);
        return;
    }
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            var userToken = context.Request.Raw.Get("token");

            if (string.IsNullOrEmpty(userToken))
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
                return;
            }

            var result = await _validator.ValidateAccessTokenAsync(userToken);

            if (result.IsError)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
                return;
            }

            // get user's identity
            var sub              = result.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.Subject)?.Value;
            var groups           = result.Claims.Where(c => c.Type == JwtClaimTypes.Role || c.Type == "groups");
            var identityProvider = result.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.IdentityProvider)?.Value ?? "local";

            context.Result = new GrantValidationResult(sub, "delegation", groups, identityProvider);
        }
Exemple #7
0
        protected override async Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            string requestToken = null;

            string authorization = Request.Headers["Authorization"];

            if (string.IsNullOrEmpty(authorization))
            {
                return(AuthenticateResult.Fail("No Authorization Header is sent."));
            }

            if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
            {
                requestToken = authorization.Substring("Bearer ".Length).Trim();
            }

            if (string.IsNullOrEmpty(requestToken))
            {
                return(AuthenticateResult.Fail("No Access Token is sent."));
            }

            TokenValidationResult result = await _tokenValidator.ValidateAccessTokenAsync(requestToken, Options.ExpectedScope);

            if (result.IsError)
            {
                return(AuthenticateResult.Fail(result.Error));
            }

            ClaimsIdentity       claimsIdentity       = new ClaimsIdentity(result.Claims, Scheme.Name);
            ClaimsPrincipal      claimsPrincipal      = new ClaimsPrincipal(claimsIdentity);
            AuthenticationTicket authenticationTicket = new AuthenticationTicket(claimsPrincipal, Scheme.Name);

            return(AuthenticateResult.Success(authenticationTicket));
        }
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            var token = context.Request.Raw.Get("access_token");
            var area  = context.Request.Raw.Get("area");

            var result = await _tokenValidator.ValidateAccessTokenAsync(token);

            if (result.IsError)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "invalid grant");
                return;
            }

            var scope = result.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.Scope && _options.ValidScopes.Contains(c.Value));

            if (scope == null)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "invalid grant");
                return;
            }

            context.Result = new GrantValidationResult(
                subject: result.Claims.FirstOrDefault(claim => claim.Type == JwtClaimTypes.Subject)?.Value,
                authenticationMethod: CustomGrantTypes.LimitedAccess,
                claims: new List <Claim> {
                new Claim("limit", area)
            });
        }
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            var requestRaw = context.Request.Raw.ToString();
            var token      = context.Request.Raw.Get("subject_token");

            if (string.IsNullOrEmpty(token))
            {
                context.Result = new GrantValidationResult(IdentityServer4.Models.TokenRequestErrors.InvalidRequest, "token missing");
                return;
            }

            var tokenValidateResult = await _tokenValidator.ValidateAccessTokenAsync(token);

            if (tokenValidateResult.IsError)
            {
                context.Result = new GrantValidationResult(IdentityServer4.Models.TokenRequestErrors.InvalidGrant, "token invalid");
                return;
            }

            var subjectClaim = tokenValidateResult.Claims.FirstOrDefault(c => c.Type == "sub");

            if (subjectClaim == null)
            {
                context.Result = new GrantValidationResult(IdentityServer4.Models.TokenRequestErrors.InvalidGrant, "token must contain sub value");
            }

            context.Result = new GrantValidationResult(subjectClaim.Value, "access token", tokenValidateResult.Claims);

            return;
        }
Exemple #10
0
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
//            var audienceName = context.Request.Raw.Get("audience");
//            var audience = await _resourceStore.FindApiResourceAsync(audienceName);

            var userToken = context.Request.Raw.Get("subject_token");

            if (string.IsNullOrEmpty(userToken))
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
                return;
            }

            var clientValidationResult = await _clientValidator.ValidateAsync(_context.HttpContext);

            var result = await _validator.ValidateAccessTokenAsync(userToken);

            if (result.IsError)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
                return;
            }
//          // get user's identity
            var sub = result.Claims.FirstOrDefault(c => c.Type == "sub")?.Value;

            context.Result = new GrantValidationResult(sub, GrantType, new []
            {
                new Claim("act",
                          JsonConvert.SerializeObject(new { sub = clientValidationResult.Client.ClientId }),
                          IdentityServerConstants.ClaimValueTypes.Json)
            });

            return;
        }
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var subject_token      = context.Request.Raw[SubjectToken];
            var subject_token_type = context.Request.Raw[SubjectTokenType];

            string errorDescription = null;

            if (subject_token == null)
            {
                errorDescription = "Missing " + SubjectToken;
            }
            else if (subject_token_type == null)
            {
                errorDescription = "Missing " + SubjectTokenType;
            }

            if (errorDescription != null)
            {
                _logger.LogError(errorDescription);
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, errorDescription);
                return;
            }

            var subjectResult =
                subject_token_type == IdTokenType ?
                await _tokenValidator.ValidateIdentityTokenAsync(subject_token, validateLifetime : false) :
                subject_token_type == AccessTokenType ?
                await _tokenValidator.ValidateAccessTokenAsync(subject_token) :
                subject_token_type == RefreshTokenType ?
                await _tokenValidator.ValidateRefreshTokenAsync(subject_token) :
                null;

            if (subjectResult.IsError)
            {
                _logger.LogError("Subject token failed to validate. {error} {errorDescription}", subjectResult.Error, subjectResult.ErrorDescription);
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "subject token validation failure");
                return;
            }

            var sub = subjectResult.Claims.SingleOrDefault(x => x.Type == JwtClaimTypes.Subject)?.Value;

            if (sub == null)
            {
                _logger.LogError("No subject claim in validated token");
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "No sub claim in subject token");
                return;
            }

            var claims = subjectResult.Claims.Where(x => !ClaimFilter.Contains(x.Type));

            context.Result = new GrantValidationResult(sub, GrantType, claims: claims.ToArray());

            _logger.LogDebug("Token exchange validator successful for subject {subjectId}", sub);
        }
    /// <summary>
    /// Validates a userinfo request.
    /// </summary>
    /// <param name="accessToken">The access token.</param>
    /// <returns></returns>
    /// <exception cref="System.NotImplementedException"></exception>
    public async Task <UserInfoRequestValidationResult> ValidateRequestAsync(string accessToken)
    {
        using var activity = Tracing.BasicActivitySource.StartActivity("UserInfoRequestValidator.ValidateRequest");

        // the access token needs to be valid and have at least the openid scope
        var tokenResult = await _tokenValidator.ValidateAccessTokenAsync(
            accessToken,
            IdentityServerConstants.StandardScopes.OpenId);

        if (tokenResult.IsError)
        {
            return(new UserInfoRequestValidationResult
            {
                IsError = true,
                Error = tokenResult.Error
            });
        }

        // the token must have a one sub claim
        var subClaim = tokenResult.Claims.SingleOrDefault(c => c.Type == JwtClaimTypes.Subject);

        if (subClaim == null)
        {
            _logger.LogError("Token contains no sub claim");

            return(new UserInfoRequestValidationResult
            {
                IsError = true,
                Error = OidcConstants.ProtectedResourceErrors.InvalidToken
            });
        }

        // create subject from incoming access token
        var claims  = tokenResult.Claims.Where(x => !Constants.Filters.ProtocolClaimsFilter.Contains(x.Type));
        var subject = Principal.Create("UserInfo", claims.ToArray());

        // make sure user is still active
        var isActiveContext = new IsActiveContext(subject, tokenResult.Client, IdentityServerConstants.ProfileIsActiveCallers.UserInfoRequestValidation);
        await _profile.IsActiveAsync(isActiveContext);

        if (isActiveContext.IsActive == false)
        {
            _logger.LogError("User is not active: {sub}", subject.GetSubjectId());

            return(new UserInfoRequestValidationResult
            {
                IsError = true,
                Error = OidcConstants.ProtectedResourceErrors.InvalidToken
            });
        }

        return(new UserInfoRequestValidationResult
        {
            IsError = false,
            TokenValidationResult = tokenResult,
            Subject = subject
        });
    }
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            var requestedTokenUse = context.Request.Raw.Get("requested_token_use");

            if (string.IsNullOrWhiteSpace(requestedTokenUse) ||
                requestedTokenUse.ToLowerInvariant() != "on_behalf_of")
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest);
                return;
            }

            var assertion = context.Request.Raw.Get("assertion");

            if (string.IsNullOrWhiteSpace(assertion))
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest);
                return;
            }

            var result = await _validator.ValidateAccessTokenAsync(assertion);

            if (result.IsError)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
                return;
            }

            // get the subject from the access token
            var subjectClaim = result.Claims.FirstOrDefault(c => c.Type == "sub");

            if (subjectClaim == null)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest);
                return;
            }

            // we've got the subject claim and the token is valid. This is where additional rules
            // can be checked that can result in not giving access, for example: checking if the user
            // is allowed access to the API (s)he wants access to  This depends on the implementation.
            //
            // ... additional checks
            //
            // This is also where claims transformation can happen, additional claims about the
            // user can be returned, etc
            //
            // ... claims transformation
            //
            // If all checks out we set the result to a GrantValidationResult, passing in
            // the users' identifier, authentication method ("access token")
            // and set of claims (in this example: the incoming claims)

            context.Result = new GrantValidationResult(subjectClaim.Value, "access_token", result.Claims);
            return;
        }
            private async Task <AuthenticateResult> CreateResultForBearerToken(string token)
            {
                var validationResult = await _tokenValidator.ValidateAccessTokenAsync(token);

                if (validationResult.IsError)
                {
                    return(AuthenticateResult.Fail("Invalid token provided"));
                }

                return(CreateSuccessResult(validationResult));
            }
        /// <inheritdoc />
        protected override async Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            _logger.LogTrace("HandleAuthenticateAsync called");

            string token = null;

            string authorization = Request.Headers["Authorization"];

            if (string.IsNullOrEmpty(authorization))
            {
                return(AuthenticateResult.Fail("No Authorization Header is sent."));
            }

            if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
            {
                token = authorization.Substring("Bearer ".Length).Trim();
            }

            if (string.IsNullOrEmpty(token))
            {
                return(AuthenticateResult.Fail("No Access Token is sent."));
            }

            _logger.LogTrace("Token found: {token}", token);

            TokenValidationResult result = await _tokenValidator.ValidateAccessTokenAsync(token, Options.ExpectedScope);

            if (result.IsError)
            {
                _logger.LogTrace("Failed to validate the token");

                return(AuthenticateResult.Fail(result.Error));
            }

            _logger.LogTrace("Successfully validated the token.");

            ClaimsIdentity           claimsIdentity           = new ClaimsIdentity(result.Claims, Scheme.Name, JwtClaimTypes.Name, JwtClaimTypes.Role);
            ClaimsPrincipal          claimsPrincipal          = new ClaimsPrincipal(claimsIdentity);
            AuthenticationProperties authenticationProperties = new AuthenticationProperties();

            if (Options.SaveToken)
            {
                authenticationProperties.StoreTokens(new[]
                {
                    new AuthenticationToken {
                        Name = "access_token", Value = token
                    }
                });
            }

            AuthenticationTicket authenticationTicket = new AuthenticationTicket(claimsPrincipal, authenticationProperties, Scheme.Name);

            return(AuthenticateResult.Success(authenticationTicket));
        }
Exemple #16
0
    /// <summary>
    /// Validates the request.
    /// </summary>
    /// <param name="parameters">The parameters.</param>
    /// <param name="api">The API.</param>
    /// <returns></returns>
    public async Task <IntrospectionRequestValidationResult> ValidateAsync(NameValueCollection parameters, ApiResource api)
    {
        using var activity = Tracing.BasicActivitySource.StartActivity("IntrospectionRequestValidator.Validate");

        _logger.LogDebug("Introspection request validation started.");

        // retrieve required token
        var token = parameters.Get("token");

        if (token == null)
        {
            _logger.LogError("Token is missing");

            return(new IntrospectionRequestValidationResult
            {
                IsError = true,
                Api = api,
                Error = "missing_token",
                Parameters = parameters
            });
        }

        // validate token
        var tokenValidationResult = await _tokenValidator.ValidateAccessTokenAsync(token);

        // invalid or unknown token
        if (tokenValidationResult.IsError)
        {
            _logger.LogDebug("Token is invalid.");

            return(new IntrospectionRequestValidationResult
            {
                IsActive = false,
                IsError = false,
                Token = token,
                Api = api,
                Parameters = parameters
            });
        }

        _logger.LogDebug("Introspection request validation successful.");

        // valid token
        return(new IntrospectionRequestValidationResult
        {
            IsActive = true,
            IsError = false,
            Token = token,
            Claims = tokenValidationResult.Claims,
            Api = api,
            Parameters = parameters
        });
    }
Exemple #17
0
        public async Task <IntrospectionRequestValidationResult> ValidateAsync(NameValueCollection parameters, Scope scope)
        {
            var fail = new IntrospectionRequestValidationResult {
                IsError = true
            };

            // retrieve required token
            var token = parameters.Get("token");

            if (token == null)
            {
                fail.IsActive      = false;
                fail.FailureReason = IntrospectionRequestValidationFailureReason.MissingToken;
                return(fail);
            }

            // validate token
            var tokenValidationResult = await _tokenValidator.ValidateAccessTokenAsync(token);

            // invalid or unknown token
            if (tokenValidationResult.IsError)
            {
                fail.IsActive      = false;
                fail.FailureReason = IntrospectionRequestValidationFailureReason.InvalidToken;
                fail.Token         = token;
                return(fail);
            }

            // check expected scope
            var expectedScope = tokenValidationResult.Claims.FirstOrDefault(
                c => c.Type == Constants.ClaimTypes.Scope && c.Value == scope.Name);

            // expected scope not present
            if (expectedScope == null)
            {
                fail.IsActive      = false;
                fail.IsError       = true;
                fail.FailureReason = IntrospectionRequestValidationFailureReason.InvalidScope;
                fail.Token         = token;
                return(fail);
            }

            // all is good
            var success = new IntrospectionRequestValidationResult
            {
                IsActive = true,
                IsError  = false,
                Token    = token,
                Claims   = tokenValidationResult.Claims
            };

            return(success);
        }
        private async Task <IEndpointResult> ProcessUserInfoRequestAsync(HttpContext context)
        {
            _logger.LogDebug("Start userinfo request");

            var tokenUsageResult = await _tokenUsageValidator.ValidateAsync(context);

            if (tokenUsageResult.TokenFound == false)
            {
                var error = "No access token found.";

                _logger.LogError(error);
                await RaiseFailureEventAsync(error);

                return(Error(OidcConstants.ProtectedResourceErrors.InvalidToken));
            }

            _logger.LogDebug("Token found: {bearerTokenUsageType}", tokenUsageResult.UsageType.ToString());

            var tokenResult = await _tokenValidator.ValidateAccessTokenAsync(
                tokenUsageResult.Token,
                Constants.StandardScopes.OpenId);

            if (tokenResult.IsError)
            {
                _logger.LogError(tokenResult.Error);
                await RaiseFailureEventAsync(tokenResult.Error);

                return(Error(tokenResult.Error));
            }

            // pass scopes/claims to profile service
            var claims  = tokenResult.Claims.Where(x => !Constants.Filters.ProtocolClaimsFilter.Contains(x.Type));
            var subject = Principal.Create("UserInfo", claims.ToArray());

            if (subject.FindFirst(JwtClaimTypes.Subject) == null)
            {
                var error = "Token contains no sub claim";
                _logger.LogError(error);
                await RaiseFailureEventAsync(error);

                return(Error(OidcConstants.ProtectedResourceErrors.InvalidToken));
            }

            var scopes = tokenResult.Claims.Where(c => c.Type == JwtClaimTypes.Scope).Select(c => c.Value);

            var payload = await _generator.ProcessAsync(subject, scopes, tokenResult.Client);

            _logger.LogDebug("End userinfo request");
            await RaiseSuccessEventAsync();

            return(new UserInfoResult(payload));
        }
        /// <summary>
        /// Revoke access token only if it belongs to client doing the request.
        /// </summary>
        protected virtual async Task <bool> RevokeAccessTokenAsync(TokenRevocationRequestValidationResult validationResult)
        {
            try
            {
                var token = await ReferenceTokenStore.GetReferenceTokenAsync(validationResult.Token);

                string subject;
                if (token != null)
                {
                    subject = token.SubjectId;
                    if (token.ClientId == validationResult.Client.ClientId)
                    {
                        Logger.LogDebug("Access token revoked");
                        await ReferenceTokenStore.RemoveReferenceTokenAsync(validationResult.Token);
                    }
                    else
                    {
                        Logger.LogWarning("Client {clientId} tried to revoke an access token belonging to a different client: {clientId}", validationResult.Client.ClientId, token.ClientId);
                    }
                }
                else
                {
                    var validateAccessToken = await _tokenValidator.ValidateAccessTokenAsync(validationResult.Token);

                    if (validateAccessToken.IsError)
                    {
                        Logger.LogWarning("Client {clientId} access_token not valid: {clientId}", validationResult.Client.ClientId, token.ClientId);
                        return(false);
                    }
                    var queryClaims = from item in validateAccessToken.Claims
                                      where item.Type == JwtClaimTypes.Subject
                                      select item.Value;
                    subject = queryClaims.FirstOrDefault();
                }

                // now we need to revoke this subject
                var rts = RefreshTokenStore as IRefreshTokenStore2;
                await rts.RemoveRefreshTokensAsync(subject, validationResult.Client.ClientId);

                var clientExtra = validationResult.Client as ClientExtra;
                await _tokenRevocationEventHandler.TokenRevokedAsync(clientExtra, subject);

                return(true);
            }
            catch (Exception e)
            {
                Logger.LogError(e, "unexpected error in revocation");
            }

            return(false);
        }
Exemple #20
0
        /// <summary>
        /// Validates the token request.
        /// </summary>
        /// <param name="context">Class describing the extension grant validation context</param>
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            var userToken    = context.Request.Raw.Get("token");
            var code         = context.Request.Raw.Get("code");
            var providerName = context.Request.Raw.Get("provider");
            var provider     = default(TotpProviderType?);
            var reason       = context.Request.Raw.Get("reason");

            if (string.IsNullOrEmpty(userToken))
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Access token 'token' parameter missing from payload.");
                return;
            }
            if (string.IsNullOrEmpty(code))
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, "Payload must provide a valid totp 'code'.");
                return;
            }
            var validationResult = await _validator.ValidateAccessTokenAsync(userToken);

            if (validationResult.IsError)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Access token validation failed");
                return;
            }
            if (!string.IsNullOrEmpty(providerName))
            {
                if (Enum.TryParse <TotpProviderType>(providerName, true, out var pv))
                {
                    provider = pv;
                }
                else
                {
                    context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, "Unsupported 'provider'.");
                    return;
                }
            }
            // Get user's identity.
            var sub        = validationResult.Claims.FirstOrDefault(x => x.Type == "sub").Value;
            var user       = new ClaimsPrincipal(new ClaimsIdentity(validationResult.Claims));
            var totpResult = await _totpService.Verify(user, code, provider, reason);

            if (!totpResult.Success)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
                return;
            }
            context.Result = new GrantValidationResult(sub, GrantType);
            return;
        }
Exemple #21
0
        public async Task <IActionResult> OnGetAsync(string secret)
        {
            var accessToken = GetTokenFromHeOader(this.HttpContext);

            if (!string.IsNullOrEmpty(accessToken))
            {
                var tokenResult = await _tokenValidator.ValidateAccessTokenAsync(accessToken);

                if (!tokenResult.IsError)
                {
                    var subClaim = tokenResult.Claims.SingleOrDefault(c => c.Type == JwtClaimTypes.Subject);
                    var openId   = subClaim.Value;

                    Input = new ConfirmDeviceLoginViewModel()
                    {
                        ConnectedId = secret, ClientName = tokenResult.Client.ClientName, ClientId = tokenResult.Client.ClientId, AccessToken = accessToken, OpenId = openId
                    };
                    return(Page());
                }
            }

            return(this.StatusCode(401));
        }
Exemple #22
0
        public async Task <IActionResult> CreateUser(string token, string returnUrl)
        {
            var validationResult = await _tokenValidator.ValidateAccessTokenAsync(token, _options.Scope);

            if (validationResult.IsError)
            {
                throw new Exception(validationResult.Error);
            }

            return(View(new CreateUserModel
            {
                Token = token,
                ReturnUrl = returnUrl
            }));
        }
        public async Task <IntrospectionRequestValidationResult> ValidateAsync(NameValueCollection parameters, ApiResource api)
        {
            // this is just for demo
            var token = parameters.Get("token");
            var tokenValidationResult = await _tokenValidator.ValidateAccessTokenAsync(token);

            return(await Task.FromResult(new IntrospectionRequestValidationResult
            {
                IsActive = true,
                IsError = false,
                Token = token,
                Claims = tokenValidationResult.Claims,
                Api = api,
                Parameters = parameters
            }));
        }
        private async Task <AuthenticateResult> BuildResult(string accessToken, string schemeName, string expectedScope, string nameClaim = "name", string roleClaim = "role")
        {
            TokenValidationResult result =
                await _tokenValidator.ValidateAccessTokenAsync(accessToken, expectedScope);

            if (result.IsError)
            {
                return(AuthenticateResult.Fail(result.Error));
            }

            ClaimsIdentity       claimsIdentity       = new ClaimsIdentity(result.Claims, schemeName, nameClaim, roleClaim);
            ClaimsPrincipal      claimsPrincipal      = new ClaimsPrincipal(claimsIdentity);
            AuthenticationTicket authenticationTicket = new AuthenticationTicket(claimsPrincipal, schemeName);

            return(AuthenticateResult.Success(authenticationTicket));
        }
Exemple #25
0
        public async Task <IEndpointResult> ProcessAsync(IdentityServerContext context)
        {
            if (context.HttpContext.Request.Method != "GET" && context.HttpContext.Request.Method != "POST")
            {
                return(new StatusCodeResult(405));
            }

            _logger.LogVerbose("Start userinfo request");

            var tokenUsageResult = await _tokenUsageValidator.ValidateAsync(context.HttpContext);

            if (tokenUsageResult.TokenFound == false)
            {
                var error = "No token found.";

                _logger.LogError(error);
                await RaiseFailureEventAsync(error);

                return(Error(OidcConstants.ProtectedResourceErrors.InvalidToken));
            }

            _logger.LogInformation("Token found: {token}", tokenUsageResult.UsageType.ToString());

            var tokenResult = await _tokenValidator.ValidateAccessTokenAsync(
                tokenUsageResult.Token,
                Constants.StandardScopes.OpenId);

            if (tokenResult.IsError)
            {
                _logger.LogError(tokenResult.Error);
                await RaiseFailureEventAsync(tokenResult.Error);

                return(Error(tokenResult.Error));
            }

            // pass scopes/claims to profile service
            var subject = tokenResult.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.Subject).Value;
            var scopes  = tokenResult.Claims.Where(c => c.Type == JwtClaimTypes.Scope).Select(c => c.Value);

            var payload = await _generator.ProcessAsync(subject, scopes, tokenResult.Client);

            _logger.LogInformation("End userinfo request");
            await RaiseSuccessEventAsync();

            return(new UserInfoResult(payload));
        }
        /// <summary>
        /// Validates the request.
        /// </summary>
        /// <param name="parameters">The parameters.</param>
        /// <returns></returns>
        public async Task <IntrospectionRequestValidationResult> ValidateAsync(NameValueCollection parameters)
        {
            _logger.LogDebug("Introspection request validation started.");

            // retrieve required token
            var token = parameters.Get("token");

            if (token == null)
            {
                _logger.LogError("Token is missing");

                return(new IntrospectionRequestValidationResult
                {
                    IsError = true,
                    Error = "missing_token"
                });
            }

            // validate token
            var tokenValidationResult = await _tokenValidator.ValidateAccessTokenAsync(token);

            // invalid or unknown token
            if (tokenValidationResult.IsError)
            {
                _logger.LogDebug("Token is invalid.");

                return(new IntrospectionRequestValidationResult
                {
                    IsActive = false,
                    IsError = false,
                    Token = token
                });
            }

            _logger.LogDebug("Introspection request validation successful.");

            // valid token
            return(new IntrospectionRequestValidationResult
            {
                IsActive = true,
                IsError = false,
                Token = token,
                Claims = tokenValidationResult.Claims
            });
        }
Exemple #27
0
        /// <summary>Validates the Custom grant request</summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            var userAccessToken    = context.Request.Raw.Get("access_token");
            var clientRefererToken = context.Request.Raw.Get("client_referer");

            if (string.IsNullOrWhiteSpace(userAccessToken))
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest);
                return;
            }

            if (string.IsNullOrWhiteSpace(clientRefererToken))
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest);
                return;
            }

            var result = await validator.ValidateAccessTokenAsync(userAccessToken).ConfigureAwait(false);

            if (result.IsError || result.Claims == null)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest);
                return;
            }

            var subjectClaim = result.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject);

            if (subjectClaim == null)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest);
                return;
            }

            var client = result.Client;

            if (client == null || !client.RedirectUris.Any(x => x.IndexOf(clientRefererToken, StringComparison.OrdinalIgnoreCase) >= 0))
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest);
            }

            context.Result = new GrantValidationResult(subjectClaim.Value, "access_token");
        }
Exemple #28
0
        /// <inheritdoc />
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            var userToken = context.Request.Raw.Get("token");

            if (string.IsNullOrEmpty(userToken))
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
                return;
            }
            var result = await _validator.ValidateAccessTokenAsync(userToken);

            if (result.IsError)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
                return;
            }
            var subject = result.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject).Value;

            context.Result = new GrantValidationResult(subject, GrantType);
        }
        /// <summary>
        /// Validates a userinfo request.
        /// </summary>
        /// <param name="accessToken">The access token.</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public async Task <UserInfoRequestValidationResult> ValidateRequestAsync(string accessToken)
        {
            // the access token needs to be valid and have at least the openid scope
            var tokenResult = await _tokenValidator.ValidateAccessTokenAsync(
                accessToken,
                IdentityServerConstants.StandardScopes.OpenId);

            if (tokenResult.IsError)
            {
                return(new UserInfoRequestValidationResult
                {
                    IsError = true,
                    Error = tokenResult.Error
                });
            }

            // the token must have a one sub claim
            var subClaim = tokenResult.Claims.SingleOrDefault(c => c.Type == JwtClaimTypes.Subject);

            if (subClaim == null)
            {
                _logger.LogError("Token contains no sub claim");

                return(new UserInfoRequestValidationResult
                {
                    IsError = true,
                    Error = OidcConstants.ProtectedResourceErrors.InvalidToken
                });
            }

            // create subject from incoming access token
            var claims  = tokenResult.Claims.Where(x => !Constants.Filters.ProtocolClaimsFilter.Contains(x.Type));
            var subject = Principal.Create("UserInfo", claims.ToArray());

            return(new UserInfoRequestValidationResult
            {
                IsError = false,
                TokenValidationResult = tokenResult,
                Subject = subject
            });
        }
        /// <summary>	Validates the asynchronous described by context. </summary>
        /// <param name="context">	The context. </param>
        /// <returns>	A Task. </returns>
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            var userToken = context.Request.Raw.Get("token");

            if (string.IsNullOrEmpty(userToken))
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
                return;
            }

            var result = await _validator.ValidateAccessTokenAsync(userToken);

            if (result.IsError)
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
                return;
            }

            var delegationAllowed =
                result.Client.Claims.Any(c => c.Type == GrantType && c.Value == context.Request.Client.ClientId);

            if (!delegationAllowed)
            {
                _logger.LogInformation(
                    $"{result.Client.ClientName} not allowed to use delegation for {context.Request.Client.ClientName} (fitting Claim is missing).");
                context.Result = new GrantValidationResult(TokenRequestErrors.UnauthorizedClient);
                return;
            }

            // get user's identity
            var sub = result.Claims.FirstOrDefault(c => c.Type == "sub").Value;

            _logger.LogInformation(
                $"Issuing DelegationGrant for {result.Claims.FirstOrDefault(c => c.Type == "email")?.Value}.");

            // grant
            context.Result = new GrantValidationResult(sub, "delegation", result.Claims);
        }