コード例 #1
0
        async public Task IsActiveAsync(IsActiveContext context)
        {
            var subject = context.Subject;
            if (subject == null) throw new ArgumentNullException(nameof(context.Subject));

            var subjectId = subject.GetSubjectId();
            var user = await _userManager.FindByIdAsync(subjectId);

            context.IsActive = false;

            if (user != null)
            {
                if (_userManager.SupportsUserSecurityStamp)
                {
                    var security_stamp = subject.Claims.Where(c => c.Type == "security_stamp").Select(c => c.Value).SingleOrDefault();
                    if (security_stamp != null)
                    {
                        var db_security_stamp = await _userManager.GetSecurityStampAsync(user);
                        if (db_security_stamp != security_stamp)
                            return;
                    }
                }

                context.IsActive =
                    !user.LockoutEnabled ||
                    !user.LockoutEnd.HasValue ||
                    user.LockoutEnd <= DateTime.Now;
            }
        }
コード例 #2
0
        private async Task <TokenRequestValidationResult> ValidateRefreshTokenRequestAsync(NameValueCollection parameters)
        {
            Logger.Info("Start validation of refresh token request");

            var refreshTokenHandle = parameters.Get(Constants.TokenRequest.RefreshToken);

            if (refreshTokenHandle.IsMissing())
            {
                var error = "Refresh token is missing";
                LogError(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(null, error);

                return(Invalid(Constants.TokenErrors.InvalidRequest));
            }

            _validatedRequest.RefreshTokenHandle = refreshTokenHandle;

            /////////////////////////////////////////////
            // check if refresh token is valid
            /////////////////////////////////////////////
            var refreshToken = await _refreshTokens.GetAsync(refreshTokenHandle);

            if (refreshToken == null)
            {
                var error = "Refresh token is invalid";
                LogWarn(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // check if refresh token has expired
            /////////////////////////////////////////////
            if (refreshToken.CreationTime.HasExceeded(refreshToken.LifeTime))
            {
                var error = "Refresh token has expired";
                LogWarn(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                await _refreshTokens.RemoveAsync(refreshTokenHandle);

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // check if client belongs to requested refresh token
            /////////////////////////////////////////////
            if (_validatedRequest.Client.ClientId != refreshToken.ClientId)
            {
                LogError(string.Format("Client {0} tries to refresh token belonging to client {1}", _validatedRequest.Client.ClientId, refreshToken.ClientId));
                await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, "Invalid client binding");

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // check if client still has offline_access scope
            /////////////////////////////////////////////
            if (!_validatedRequest.Client.AllowAccessToAllScopes)
            {
                if (!_validatedRequest.Client.AllowedScopes.Contains(Constants.StandardScopes.OfflineAccess))
                {
                    var error = "Client does not have access to offline_access scope anymore";
                    LogError(error);
                    await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                    return(Invalid(Constants.TokenErrors.InvalidGrant));
                }
            }

            _validatedRequest.RefreshToken = refreshToken;

            /////////////////////////////////////////////
            // make sure user is enabled
            /////////////////////////////////////////////
            var principal = IdentityServerPrincipal.FromSubjectId(_validatedRequest.RefreshToken.SubjectId, refreshToken.AccessToken.Claims);

            var isActiveCtx = new IsActiveContext(principal, _validatedRequest.Client);
            await _users.IsActiveAsync(isActiveCtx);

            if (isActiveCtx.IsActive == false)
            {
                var error = "User has been disabled: " + _validatedRequest.RefreshToken.SubjectId;
                LogError(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                return(Invalid(Constants.TokenErrors.InvalidRequest));
            }

            Logger.Info("Validation of refresh token request success");
            return(Valid());
        }
コード例 #3
0
        public async Task IsActiveAsync(IsActiveContext context)
        {
            var subjectId = context.Subject.GetSubjectId();

            context.IsActive = await _localUserService.IsUserActive(subjectId);
        }
コード例 #4
0
        /// <summary>
        /// Validates the device code.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        public async Task ValidateAsync(DeviceCodeValidationContext context)
        {
            var deviceCode = await _devices.FindByDeviceCodeAsync(context.DeviceCode);

            if (deviceCode == null)
            {
                _logger.LogError("Invalid device code");
                context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.InvalidGrant);
                return;
            }

            // validate client binding
            if (deviceCode.ClientId != context.Request.Client.ClientId)
            {
                _logger.LogError("Client {0} is trying to use a device code from client {1}", context.Request.Client.ClientId, deviceCode.ClientId);
                context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.InvalidGrant);
                return;
            }

            if (await _throttlingService.ShouldSlowDown(context.DeviceCode, deviceCode))
            {
                _logger.LogError("Client {0} is polling too fast", deviceCode.ClientId);
                context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.SlowDown);
                return;
            }

            // validate lifetime
            if (deviceCode.CreationTime.AddSeconds(deviceCode.Lifetime) < _systemClock.UtcNow)
            {
                _logger.LogError("Expired device code");
                context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.ExpiredToken);
                return;
            }

            // denied
            if (deviceCode.IsAuthorized &&
                (deviceCode.AuthorizedScopes == null || deviceCode.AuthorizedScopes.Any() == false))
            {
                _logger.LogError("No scopes authorized for device authorization. Access denied");
                context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.AccessDenied);
                return;
            }

            // make sure code is authorized
            if (!deviceCode.IsAuthorized || deviceCode.Subject == null)
            {
                context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.AuthorizationPending);
                return;
            }

            // make sure user is enabled
            var isActiveCtx = new IsActiveContext(deviceCode.Subject, context.Request.Client, IdentityServerConstants.ProfileIsActiveCallers.DeviceCodeValidation);
            await _profile.IsActiveAsync(isActiveCtx);

            if (!isActiveCtx.IsActive)
            {
                _logger.LogError("User has been disabled: {subjectId}", deviceCode.Subject.GetSubjectId());
                context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.InvalidGrant);
                return;
            }

            context.Request.DeviceCode = deviceCode;
            context.Request.SessionId  = deviceCode.SessionId;

            context.Result = new TokenRequestValidationResult(context.Request);
            await _devices.RemoveByDeviceCodeAsync(context.DeviceCode);
        }
コード例 #5
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public Task IsActiveAsync(IsActiveContext context)
 {
     // check already done during validation
     return(Task.CompletedTask);
 }
コード例 #6
0
        private async Task <TokenRequestValidationResult> ValidateRefreshTokenRequestAsync(NameValueCollection parameters)
        {
            Logger.Info("Start validation of refresh token request");

            var refreshTokenHandle = parameters.Get(Constants.TokenRequest.RefreshToken);

            if (refreshTokenHandle.IsMissing())
            {
                var error = "Refresh token is missing";
                LogError(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(null, error);

                return(Invalid(Constants.TokenErrors.InvalidRequest));
            }

            if (refreshTokenHandle.Length > _options.InputLengthRestrictions.RefreshToken)
            {
                var error = "Refresh token too long";
                LogError(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(null, error);

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            _validatedRequest.RefreshTokenHandle = refreshTokenHandle;

            /////////////////////////////////////////////
            // check if refresh token is valid
            /////////////////////////////////////////////
            var refreshToken = await _refreshTokens.GetAsync(refreshTokenHandle);

            if (refreshToken == null)
            {
                var error = "Refresh token is invalid";
                LogWarn(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // check if refresh token has expired
            /////////////////////////////////////////////
            if (refreshToken.CreationTime.HasExceeded(refreshToken.LifeTime))
            {
                var error = "Refresh token has expired";
                LogWarn(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                await _refreshTokens.RemoveAsync(refreshTokenHandle);

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // check if client belongs to requested refresh token
            /////////////////////////////////////////////
            if (_validatedRequest.Client.ClientId != refreshToken.ClientId)
            {
                LogError(string.Format("Client {0} tries to refresh token belonging to client {1}", _validatedRequest.Client.ClientId, refreshToken.ClientId));
                await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, "Invalid client binding");

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // check if client still has offline_access scope
            /////////////////////////////////////////////
            if (!_validatedRequest.Client.AllowAccessToAllScopes)
            {
                if (!_validatedRequest.Client.AllowedScopes.Contains(Constants.StandardScopes.OfflineAccess))
                {
                    var error = "Client does not have access to offline_access scope anymore";
                    LogError(error);
                    await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                    return(Invalid(Constants.TokenErrors.InvalidGrant));
                }
            }

            /////////////////////////////////////////////
            // check if client still has access to
            // all scopes from the original token request
            /////////////////////////////////////////////
            if (!_validatedRequest.Client.AllowAccessToAllScopes)
            {
                foreach (var scope in refreshToken.Scopes)
                {
                    if (!_validatedRequest.Client.AllowedScopes.Contains(scope))
                    {
                        var error = "Client does not have access to a requested scope anymore: " + scope;
                        LogError(error);
                        await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                        return(Invalid(Constants.TokenErrors.InvalidGrant));
                    }
                }
            }

            _validatedRequest.RefreshToken = refreshToken;

            /////////////////////////////////////////////
            // make sure user is enabled
            /////////////////////////////////////////////
            var principal = IdentityServerPrincipal.FromSubjectId(_validatedRequest.RefreshToken.SubjectId, refreshToken.AccessToken.Claims);

            var isActiveCtx = new IsActiveContext(principal, _validatedRequest.Client);
            await _users.IsActiveAsync(isActiveCtx);

            if (isActiveCtx.IsActive == false)
            {
                var error = "User has been disabled: " + _validatedRequest.RefreshToken.SubjectId;
                LogError(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                return(Invalid(Constants.TokenErrors.InvalidRequest));
            }

            /////////////////////////////////////////////
            // validate token type and PoP parameters if pop token is requested
            /////////////////////////////////////////////
            var tokenType = parameters.Get("token_type");

            if (tokenType != null && tokenType == "pop")
            {
                var result = ValidatePopParameters(parameters);
                if (result.IsError)
                {
                    var error = "PoP parameter validation failed: " + result.ErrorDescription;
                    LogError(error);
                    await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                    return(Invalid(result.Error, result.ErrorDescription));
                }
                else
                {
                    _validatedRequest.RequestedTokenType = RequestedTokenTypes.PoP;
                }
            }

            Logger.Info("Validation of refresh token request success");
            return(Valid());
        }
コード例 #7
0
 public Task IsActiveAsync(IsActiveContext context)
 {
     context.IsActive = true;
     return(Task.FromResult(true));
 }
コード例 #8
0
 public override Task IsActiveAsync(IsActiveContext context)
 {
     return(base.IsActiveAsync(context));
 }
コード例 #9
0
 public Task IsActiveAsync(IsActiveContext context) => Task.CompletedTask;
コード例 #10
0
        public virtual async Task IsActiveAsync(IsActiveContext context)
        {
            var user = await GetUser(context.Subject);

            context.IsActive = !_options.RequireConfirmedEmail || (user?.EmailConfirmed ?? false);
        }
コード例 #11
0
        public async Task IsActiveAsync(IsActiveContext context)
        {
            var user = await _userManager.GetUserAsync(context.Subject);

            context.IsActive = user != null;
        }
コード例 #12
0
        private async Task <TokenRequestValidationResult> ValidateExtensionGrantRequestAsync(NameValueCollection parameters)
        {
            _logger.LogDebug("Start validation of custom grant token request");

            /////////////////////////////////////////////
            // check if client is allowed to use grant type
            /////////////////////////////////////////////
            if (!_validatedRequest.Client.AllowedGrantTypes.Contains(_validatedRequest.GrantType))
            {
                LogError("Client does not have the custom grant type in the allowed list, therefore requested grant is not allowed", new { clientId = _validatedRequest.Client.ClientId });
                return(Invalid(OidcConstants.TokenErrors.UnsupportedGrantType));
            }

            /////////////////////////////////////////////
            // check if a validator is registered for the grant type
            /////////////////////////////////////////////
            if (!_extensionGrantValidator.GetAvailableGrantTypes().Contains(_validatedRequest.GrantType, StringComparer.Ordinal))
            {
                LogError("No validator is registered for the grant type", new { grantType = _validatedRequest.GrantType });
                return(Invalid(OidcConstants.TokenErrors.UnsupportedGrantType));
            }

            /////////////////////////////////////////////
            // check if client is allowed to request scopes
            /////////////////////////////////////////////
            if (!await ValidateRequestedScopesAsync(parameters))
            {
                return(Invalid(OidcConstants.TokenErrors.InvalidScope));
            }

            /////////////////////////////////////////////
            // validate custom grant type
            /////////////////////////////////////////////
            var result = await _extensionGrantValidator.ValidateAsync(_validatedRequest);

            if (result == null)
            {
                LogError("Invalid extension grant");
                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            if (result.IsError)
            {
                if (result.Error.IsPresent())
                {
                    LogError("Invalid extension grant", new { error = result.Error });
                    return(Invalid(result.Error, result.ErrorDescription, result.CustomResponse));
                }
                else
                {
                    LogError("Invalid extension grant");
                    return(Invalid(OidcConstants.TokenErrors.InvalidGrant, customResponse: result.CustomResponse));
                }
            }

            if (result.Subject != null)
            {
                /////////////////////////////////////////////
                // make sure user is enabled
                /////////////////////////////////////////////
                var isActiveCtx = new IsActiveContext(
                    result.Subject,
                    _validatedRequest.Client,
                    IdentityServerConstants.ProfileIsActiveCallers.ExtensionGrantValidation);

                await _profile.IsActiveAsync(isActiveCtx);

                if (isActiveCtx.IsActive == false)
                {
                    // todo: raise event?

                    LogError("User has been disabled", new { subjectId = result.Subject.GetSubjectId() });
                    return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
                }

                _validatedRequest.Subject = result.Subject;
            }

            _logger.LogDebug("Validation of extension grant token request success");
            return(Valid(result.CustomResponse));
        }
コード例 #13
0
        private async Task <TokenRequestValidationResult> ValidateResourceOwnerCredentialRequestAsync(NameValueCollection parameters)
        {
            _logger.LogDebug("Start resource owner password token request validation");

            /////////////////////////////////////////////
            // check if client is authorized for grant type
            /////////////////////////////////////////////
            if (!_validatedRequest.Client.AllowedGrantTypes.Contains(GrantType.ResourceOwnerPassword))
            {
                LogError("Client not authorized for resource owner flow, check the AllowedGrantTypes setting", new { client_id = _validatedRequest.Client.ClientId });
                return(Invalid(OidcConstants.TokenErrors.UnauthorizedClient));
            }

            /////////////////////////////////////////////
            // check if client is allowed to request scopes
            /////////////////////////////////////////////
            if (!(await ValidateRequestedScopesAsync(parameters)))
            {
                return(Invalid(OidcConstants.TokenErrors.InvalidScope));
            }

            /////////////////////////////////////////////
            // check resource owner credentials
            /////////////////////////////////////////////
            var userName = parameters.Get(OidcConstants.TokenRequest.UserName);
            var password = parameters.Get(OidcConstants.TokenRequest.Password);

            if (userName.IsMissing())
            {
                LogError("Username is missing");
                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            if (password.IsMissing())
            {
                password = "";
            }

            if (userName.Length > _options.InputLengthRestrictions.UserName ||
                password.Length > _options.InputLengthRestrictions.Password)
            {
                LogError("Username or password too long");
                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            _validatedRequest.UserName = userName;


            /////////////////////////////////////////////
            // authenticate user
            /////////////////////////////////////////////
            var resourceOwnerContext = new ResourceOwnerPasswordValidationContext
            {
                UserName = userName,
                Password = password,
                Request  = _validatedRequest
            };
            await _resourceOwnerValidator.ValidateAsync(resourceOwnerContext);

            if (resourceOwnerContext.Result.IsError)
            {
                // protect against bad validator implementations
                resourceOwnerContext.Result.Error ??= OidcConstants.TokenErrors.InvalidGrant;

                if (resourceOwnerContext.Result.Error == OidcConstants.TokenErrors.UnsupportedGrantType)
                {
                    LogError("Resource owner password credential grant type not supported");
                    await RaiseFailedResourceOwnerAuthenticationEventAsync(userName, "password grant type not supported", resourceOwnerContext.Request.Client.ClientId);

                    return(Invalid(OidcConstants.TokenErrors.UnsupportedGrantType, customResponse: resourceOwnerContext.Result.CustomResponse));
                }

                var errorDescription = "invalid_username_or_password";

                if (resourceOwnerContext.Result.ErrorDescription.IsPresent())
                {
                    errorDescription = resourceOwnerContext.Result.ErrorDescription;
                }

                LogInformation("User authentication failed: ", errorDescription ?? resourceOwnerContext.Result.Error);
                await RaiseFailedResourceOwnerAuthenticationEventAsync(userName, errorDescription, resourceOwnerContext.Request.Client.ClientId);

                return(Invalid(resourceOwnerContext.Result.Error, errorDescription, resourceOwnerContext.Result.CustomResponse));
            }

            if (resourceOwnerContext.Result.Subject == null)
            {
                var error = "User authentication failed: no principal returned";
                LogError(error);
                await RaiseFailedResourceOwnerAuthenticationEventAsync(userName, error, resourceOwnerContext.Request.Client.ClientId);

                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // make sure user is enabled
            /////////////////////////////////////////////
            var isActiveCtx = new IsActiveContext(resourceOwnerContext.Result.Subject, _validatedRequest.Client, IdentityServerConstants.ProfileIsActiveCallers.ResourceOwnerValidation);
            await _profile.IsActiveAsync(isActiveCtx);

            if (isActiveCtx.IsActive == false)
            {
                LogError("User has been disabled", new { subjectId = resourceOwnerContext.Result.Subject.GetSubjectId() });
                await RaiseFailedResourceOwnerAuthenticationEventAsync(userName, "user is inactive", resourceOwnerContext.Request.Client.ClientId);

                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            _validatedRequest.UserName = userName;
            _validatedRequest.Subject  = resourceOwnerContext.Result.Subject;

            await RaiseSuccessfulResourceOwnerAuthenticationEventAsync(userName, resourceOwnerContext.Result.Subject.GetSubjectId(), resourceOwnerContext.Request.Client.ClientId);

            _logger.LogDebug("Resource owner password token request validation success.");
            return(Valid(resourceOwnerContext.Result.CustomResponse));
        }
コード例 #14
0
        private async Task <TokenRequestValidationResult> ValidateAuthorizationCodeRequestAsync(NameValueCollection parameters)
        {
            _logger.LogDebug("Start validation of authorization code token request");

            /////////////////////////////////////////////
            // check if client is authorized for grant type
            /////////////////////////////////////////////
            if (!_validatedRequest.Client.AllowedGrantTypes.ToList().Contains(GrantType.AuthorizationCode) &&
                !_validatedRequest.Client.AllowedGrantTypes.ToList().Contains(GrantType.Hybrid))
            {
                LogError("Client not authorized for code flow");
                return(Invalid(OidcConstants.TokenErrors.UnauthorizedClient));
            }

            /////////////////////////////////////////////
            // validate authorization code
            /////////////////////////////////////////////
            var code = parameters.Get(OidcConstants.TokenRequest.Code);

            if (code.IsMissing())
            {
                LogError("Authorization code is missing");
                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            if (code.Length > _options.InputLengthRestrictions.AuthorizationCode)
            {
                LogError("Authorization code is too long");
                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            _validatedRequest.AuthorizationCodeHandle = code;

            var authZcode = await _authorizationCodeStore.GetAuthorizationCodeAsync(code);

            if (authZcode == null)
            {
                LogError("Invalid authorization code", new { code });
                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            await _authorizationCodeStore.RemoveAuthorizationCodeAsync(code);

            if (authZcode.CreationTime.HasExceeded(authZcode.Lifetime, _clock.UtcNow.UtcDateTime))
            {
                LogError("Authorization code expired", new { code });
                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // populate session id
            /////////////////////////////////////////////
            if (authZcode.SessionId.IsPresent())
            {
                _validatedRequest.SessionId = authZcode.SessionId;
            }

            /////////////////////////////////////////////
            // validate client binding
            /////////////////////////////////////////////
            if (authZcode.ClientId != _validatedRequest.Client.ClientId)
            {
                LogError("Client is trying to use a code from a different client", new { clientId = _validatedRequest.Client.ClientId, codeClient = authZcode.ClientId });
                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // validate code expiration
            /////////////////////////////////////////////
            if (authZcode.CreationTime.HasExceeded(_validatedRequest.Client.AuthorizationCodeLifetime, _clock.UtcNow.UtcDateTime))
            {
                LogError("Authorization code is expired");
                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            _validatedRequest.AuthorizationCode = authZcode;
            _validatedRequest.Subject           = authZcode.Subject;

            /////////////////////////////////////////////
            // validate redirect_uri
            /////////////////////////////////////////////
            var redirectUri = parameters.Get(OidcConstants.TokenRequest.RedirectUri);

            if (redirectUri.IsMissing())
            {
                LogError("Redirect URI is missing");
                return(Invalid(OidcConstants.TokenErrors.UnauthorizedClient));
            }

            if (redirectUri.Equals(_validatedRequest.AuthorizationCode.RedirectUri, StringComparison.Ordinal) == false)
            {
                LogError("Invalid redirect_uri", new { redirectUri, expectedRedirectUri = _validatedRequest.AuthorizationCode.RedirectUri });
                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // validate scopes are present
            /////////////////////////////////////////////
            if (_validatedRequest.AuthorizationCode.RequestedScopes == null ||
                !_validatedRequest.AuthorizationCode.RequestedScopes.Any())
            {
                LogError("Authorization code has no associated scopes");
                return(Invalid(OidcConstants.TokenErrors.InvalidRequest));
            }

            /////////////////////////////////////////////
            // validate PKCE parameters
            /////////////////////////////////////////////
            var codeVerifier = parameters.Get(OidcConstants.TokenRequest.CodeVerifier);

            if (_validatedRequest.Client.RequirePkce || _validatedRequest.AuthorizationCode.CodeChallenge.IsPresent())
            {
                _logger.LogDebug("Client required a proof key for code exchange. Starting PKCE validation");

                var proofKeyResult = ValidateAuthorizationCodeWithProofKeyParameters(codeVerifier, _validatedRequest.AuthorizationCode);
                if (proofKeyResult.IsError)
                {
                    return(proofKeyResult);
                }

                _validatedRequest.CodeVerifier = codeVerifier;
            }
            else
            {
                if (codeVerifier.IsPresent())
                {
                    LogError("Unexpected code_verifier: {codeVerifier}. This happens when the client is trying to use PKCE, but it is not enabled. Set RequirePkce to true.", codeVerifier);
                    return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
                }
            }

            /////////////////////////////////////////////
            // make sure user is enabled
            /////////////////////////////////////////////
            var isActiveCtx = new IsActiveContext(_validatedRequest.AuthorizationCode.Subject, _validatedRequest.Client, IdentityServerConstants.ProfileIsActiveCallers.AuthorizationCodeValidation);
            await _profile.IsActiveAsync(isActiveCtx);

            if (isActiveCtx.IsActive == false)
            {
                LogError("User has been disabled", new { subjectId = _validatedRequest.AuthorizationCode.Subject.GetSubjectId() });
                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            _logger.LogDebug("Validation of authorization code token request success");

            return(Valid());
        }
コード例 #15
0
 public Task IsActiveAsync(IsActiveContext context)
 {
     context.IsActive = true;
     return(Task.CompletedTask);
     // throw new NotImplementedException();
 }
    /// <inheritdoc/>
    public async Task ValidateAsync(BackchannelAuthenticationRequestIdValidationContext context)
    {
        using var activity = Tracing.BasicActivitySource.StartActivity("BackchannelAuthenticationRequestIdValidator.Validate");

        var request = await _backchannelAuthenticationStore.GetByAuthenticationRequestIdAsync(context.AuthenticationRequestId);

        if (request == null)
        {
            _logger.LogError("Invalid authentication request id");
            context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.InvalidGrant);
            return;
        }

        // validate client binding
        if (request.ClientId != context.Request.Client.ClientId)
        {
            _logger.LogError("Client {0} is trying to use a authentication request id from client {1}", context.Request.Client.ClientId, request.ClientId);
            context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.InvalidGrant);
            return;
        }

        if (await _throttlingService.ShouldSlowDown(context.AuthenticationRequestId, request))
        {
            _logger.LogError("Client {0} is polling too fast", request.ClientId);
            context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.SlowDown);
            return;
        }

        // validate lifetime
        if (request.CreationTime.AddSeconds(request.Lifetime) < _systemClock.UtcNow.UtcDateTime)
        {
            _logger.LogError("Expired authentication request id");
            context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.ExpiredToken);
            return;
        }

        // denied
        if (request.IsComplete &&
            (request.AuthorizedScopes == null || request.AuthorizedScopes.Any() == false))
        {
            _logger.LogError("No scopes authorized for backchannel authentication request. Access denied");
            context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.AccessDenied);
            await _backchannelAuthenticationStore.RemoveByInternalIdAsync(request.InternalId);

            return;
        }

        // make sure authentication request id is complete
        if (!request.IsComplete)
        {
            context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.AuthorizationPending);
            return;
        }

        // make sure user is enabled
        var isActiveCtx = new IsActiveContext(request.Subject, context.Request.Client, IdentityServerConstants.ProfileIsActiveCallers.BackchannelAuthenticationRequestIdValidation);
        await _profile.IsActiveAsync(isActiveCtx);

        if (isActiveCtx.IsActive == false)
        {
            _logger.LogError("User has been disabled: {subjectId}", request.Subject.GetSubjectId());
            context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.InvalidGrant);
            return;
        }

        context.Request.BackChannelAuthenticationRequest = request;
        context.Request.Subject   = request.Subject;
        context.Request.SessionId = request.SessionId;

        context.Result = new TokenRequestValidationResult(context.Request);

        await _backchannelAuthenticationStore.RemoveByInternalIdAsync(request.InternalId);

        _logger.LogDebug("Success validating backchannel authentication request id.");
    }
コード例 #17
0
        private async Task <TokenRequestValidationResult> ValidateAuthorizationCodeRequestAsync(NameValueCollection parameters)
        {
            Logger.Info("Start validation of authorization code token request");

            /////////////////////////////////////////////
            // check if client is authorized for grant type
            /////////////////////////////////////////////
            if (Constants.AllowedFlowsForAuthorizationCodeGrantType.Contains(_validatedRequest.Client.Flow) == false)
            {
                LogError("Client not authorized for code flow");
                return(Invalid(Constants.TokenErrors.UnauthorizedClient));
            }

            /////////////////////////////////////////////
            // validate authorization code
            /////////////////////////////////////////////
            var code = parameters.Get(Constants.TokenRequest.Code);

            if (code.IsMissing())
            {
                var error = "Authorization code is missing.";
                LogError(error);
                await RaiseFailedAuthorizationCodeRedeemedEventAsync(null, error);

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            if (code.Length > _options.InputLengthRestrictions.AuthorizationCode)
            {
                var error = "Authorization code is too long.";
                LogError(error);
                await RaiseFailedAuthorizationCodeRedeemedEventAsync(null, error);

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            _validatedRequest.AuthorizationCodeHandle = code;

            var authZcode = await _authorizationCodes.GetAsync(code);

            if (authZcode == null)
            {
                LogError("Invalid authorization code: " + code);
                await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, "Invalid handle");

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            await _authorizationCodes.RemoveAsync(code);

            /////////////////////////////////////////////
            // populate session id
            /////////////////////////////////////////////
            if (authZcode.SessionId.IsPresent())
            {
                _validatedRequest.SessionId = authZcode.SessionId;
            }

            /////////////////////////////////////////////
            // validate client binding
            /////////////////////////////////////////////
            if (authZcode.Client.ClientId != _validatedRequest.Client.ClientId)
            {
                LogError(string.Format("Client {0} is trying to use a code from client {1}", _validatedRequest.Client.ClientId, authZcode.Client.ClientId));
                await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, "Invalid client binding");

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // validate PKCE parameters
            /////////////////////////////////////////////
            var codeVerifier = parameters.Get(Constants.TokenRequest.CodeVerifier);

            if (authZcode.Client.Flow == Flows.AuthorizationCodeWithProofKey ||
                authZcode.Client.Flow == Flows.HybridWithProofKey)
            {
                var proofKeyResult = ValidateAuthorizationCodeWithProofKeyParameters(codeVerifier, authZcode);
                if (proofKeyResult.IsError)
                {
                    return(proofKeyResult);
                }

                _validatedRequest.CodeVerifier = codeVerifier;
            }
            else
            {
                if (codeVerifier.IsPresent())
                {
                    LogError("Unexpected code_verifier with Flow " + authZcode.Client.Flow.ToString());
                    return(Invalid(Constants.TokenErrors.InvalidGrant));
                }
            }

            /////////////////////////////////////////////
            // validate code expiration
            /////////////////////////////////////////////
            if (authZcode.CreationTime.HasExceeded(_validatedRequest.Client.AuthorizationCodeLifetime))
            {
                var error = "Authorization code is expired";
                LogError(error);
                await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error);

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            _validatedRequest.AuthorizationCode = authZcode;

            /////////////////////////////////////////////
            // validate redirect_uri
            /////////////////////////////////////////////
            var redirectUri = parameters.Get(Constants.TokenRequest.RedirectUri);

            if (redirectUri.IsMissing())
            {
                var error = "Redirect URI is missing.";
                LogError(error);
                await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error);

                return(Invalid(Constants.TokenErrors.UnauthorizedClient));
            }

            if (redirectUri.Equals(_validatedRequest.AuthorizationCode.RedirectUri, StringComparison.Ordinal) == false)
            {
                var error = "Invalid redirect_uri: " + redirectUri;
                LogError(error);
                await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error);

                return(Invalid(Constants.TokenErrors.UnauthorizedClient));
            }

            /////////////////////////////////////////////
            // validate scopes are present
            /////////////////////////////////////////////
            if (_validatedRequest.AuthorizationCode.RequestedScopes == null ||
                !_validatedRequest.AuthorizationCode.RequestedScopes.Any())
            {
                var error = "Authorization code has no associated scopes.";
                LogError(error);
                await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error);

                return(Invalid(Constants.TokenErrors.InvalidRequest));
            }


            /////////////////////////////////////////////
            // make sure user is enabled
            /////////////////////////////////////////////
            var isActiveCtx = new IsActiveContext(_validatedRequest.AuthorizationCode.Subject, _validatedRequest.Client);
            await _users.IsActiveAsync(isActiveCtx);

            if (isActiveCtx.IsActive == false)
            {
                var error = "User has been disabled: " + _validatedRequest.AuthorizationCode.Subject;
                LogError(error);
                await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error);

                return(Invalid(Constants.TokenErrors.InvalidRequest));
            }

            /////////////////////////////////////////////
            // validate token type and PoP parameters if pop token is requested
            /////////////////////////////////////////////
            var tokenType = parameters.Get("token_type");

            if (tokenType != null && tokenType == Constants.ResponseTokenTypes.PoP)
            {
                var result = ValidatePopParameters(parameters);
                if (result.IsError)
                {
                    var error = "PoP parameter validation failed: " + result.ErrorDescription;
                    LogError(error);
                    await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error);

                    return(Invalid(result.Error, result.ErrorDescription));
                }
                else
                {
                    _validatedRequest.RequestedTokenType = RequestedTokenTypes.PoP;
                }
            }

            Logger.Info("Validation of authorization code token request success");
            await RaiseSuccessfulAuthorizationCodeRedeemedEventAsync();

            return(Valid());
        }
コード例 #18
0
        /// <summary>
        /// Processes the login logic.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns></returns>
        protected internal virtual async Task <InteractionResponse> ProcessLoginAsync(ValidatedAuthorizeRequest request)
        {
            if (request.PromptMode == OidcConstants.PromptModes.Login ||
                request.PromptMode == OidcConstants.PromptModes.SelectAccount)
            {
                // remove prompt so when we redirect back in from login page
                // we won't think we need to force a prompt again
                request.RemovePrompt();

                _logger.LogInformation("Showing login: request contains prompt={0}", request.PromptMode);

                return(new InteractionResponse()
                {
                    IsLogin = true
                });
            }

            // unauthenticated user
            var isAuthenticated = request.Subject.IsAuthenticated();

            // user de-activated
            bool isActive = false;

            if (isAuthenticated)
            {
                var isActiveCtx = new IsActiveContext(request.Subject, request.Client, IdentityServerConstants.ProfileIsActiveCallers.AuthorizeEndpoint);
                await _profile.IsActiveAsync(isActiveCtx);

                isActive = isActiveCtx.IsActive;
            }

            if (!isAuthenticated || !isActive)
            {
                // prompt=none means user must be signed in already
                if (request.PromptMode == OidcConstants.PromptModes.None)
                {
                    if (!isAuthenticated)
                    {
                        _logger.LogInformation("Showing error: prompt=none was requested but user is not authenticated");
                    }
                    else if (!isActive)
                    {
                        _logger.LogInformation("Showing error: prompt=none was requested but user is not active");
                    }

                    return(new InteractionResponse
                    {
                        Error = OidcConstants.AuthorizeErrors.LoginRequired,
                    });
                }

                if (!isAuthenticated)
                {
                    _logger.LogInformation("Showing login: User is not authenticated");
                }
                else if (!isActive)
                {
                    _logger.LogInformation("Showing login: User is not active");
                }

                return(new InteractionResponse()
                {
                    IsLogin = true
                });
            }

            // check current idp
            var currentIdp = request.Subject.GetIdentityProvider();

            // check if idp login hint matches current provider
            var idp = request.GetIdP();

            if (idp.IsPresent())
            {
                if (idp != currentIdp)
                {
                    _logger.LogInformation("Showing login: Current IdP ({idp}) is not the requested IdP ({idp})", currentIdp, idp);
                    return(new InteractionResponse()
                    {
                        IsLogin = true
                    });
                }
            }

            // check authentication freshness
            if (request.MaxAge.HasValue)
            {
                var authTime = request.Subject.GetAuthenticationTime();
                if (IdentityServerDateTime.UtcNow > authTime.AddSeconds(request.MaxAge.Value))
                {
                    _logger.LogInformation("Showing login: Requested MaxAge exceeded.");

                    return(new InteractionResponse()
                    {
                        IsLogin = true
                    });
                }
            }

            // check local idp restrictions
            if (currentIdp == IdentityServerConstants.LocalIdentityProvider && !request.Client.EnableLocalLogin)
            {
                _logger.LogInformation("Showing login: User logged in locally, but client does not allow local logins");
                return(new InteractionResponse()
                {
                    IsLogin = true
                });
            }

            // check external idp restrictions
            if (request.Client.IdentityProviderRestrictions != null && request.Client.IdentityProviderRestrictions.Any())
            {
                if (!request.Client.IdentityProviderRestrictions.Contains(currentIdp))
                {
                    _logger.LogInformation("Showing login: User is logged in with idp: {idp}, but idp not in client restriction list.", currentIdp);
                    return(new InteractionResponse()
                    {
                        IsLogin = true
                    });
                }
            }

            return(new InteractionResponse());
        }
コード例 #19
0
ファイル: ProfileService.cs プロジェクト: zz110/archives
 public async Task IsActiveAsync(IsActiveContext context)
 {
     await Task.Run(() => context.IsActive = true);
 }
コード例 #20
0
        /// <summary>
        /// Processes the login logic.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns></returns>
        protected internal virtual async Task <InteractionResponse> ProcessLoginAsync(ValidatedAuthorizeRequest request)
        {
            if (request.PromptModes.Contains(OidcConstants.PromptModes.Login) ||
                request.PromptModes.Contains(OidcConstants.PromptModes.SelectAccount))
            {
                Logger.LogInformation("Showing login: request contains prompt={0}", request.PromptModes.ToSpaceSeparatedString());

                // remove prompt so when we redirect back in from login page
                // we won't think we need to force a prompt again
                request.RemovePrompt();

                return(new InteractionResponse {
                    IsLogin = true
                });
            }

            // unauthenticated user
            var isAuthenticated = request.Subject.IsAuthenticated();

            // user de-activated
            bool isActive = false;

            if (isAuthenticated)
            {
                var isActiveCtx = new IsActiveContext(request.Subject, request.Client, IdentityServerConstants.ProfileIsActiveCallers.AuthorizeEndpoint);
                await Profile.IsActiveAsync(isActiveCtx);

                isActive = isActiveCtx.IsActive;
            }

            if (!isAuthenticated || !isActive)
            {
                if (!isAuthenticated)
                {
                    Logger.LogInformation("Showing login: User is not authenticated");
                }
                else if (!isActive)
                {
                    Logger.LogInformation("Showing login: User is not active");
                }

                return(new InteractionResponse {
                    IsLogin = true
                });
            }

            // check current idp
            var currentIdp = request.Subject.GetIdentityProvider();

            // check if idp login hint matches current provider
            var idp = request.GetIdP();

            if (idp.IsPresent())
            {
                if (idp != currentIdp)
                {
                    Logger.LogInformation("Showing login: Current IdP ({currentIdp}) is not the requested IdP ({idp})", currentIdp, idp);
                    return(new InteractionResponse {
                        IsLogin = true
                    });
                }
            }

            // check authentication freshness
            if (request.MaxAge.HasValue)
            {
                var authTime = request.Subject.GetAuthenticationTime();
                if (Clock.UtcNow > authTime.AddSeconds(request.MaxAge.Value))
                {
                    Logger.LogInformation("Showing login: Requested MaxAge exceeded.");

                    return(new InteractionResponse {
                        IsLogin = true
                    });
                }
            }

            // check local idp restrictions
            if (currentIdp == IdentityServerConstants.LocalIdentityProvider)
            {
                if (!request.Client.EnableLocalLogin)
                {
                    Logger.LogInformation("Showing login: User logged in locally, but client does not allow local logins");
                    return(new InteractionResponse {
                        IsLogin = true
                    });
                }
            }
            // check external idp restrictions if user not using local idp
            else if (request.Client.IdentityProviderRestrictions != null &&
                     request.Client.IdentityProviderRestrictions.Any() &&
                     !request.Client.IdentityProviderRestrictions.Contains(currentIdp))
            {
                Logger.LogInformation("Showing login: User is logged in with idp: {idp}, but idp not in client restriction list.", currentIdp);
                return(new InteractionResponse {
                    IsLogin = true
                });
            }

            // check client's user SSO timeout
            if (request.Client.UserSsoLifetime.HasValue)
            {
                var authTimeEpoch = request.Subject.GetAuthenticationTimeEpoch();
                var nowEpoch      = Clock.UtcNow.ToUnixTimeSeconds();

                var diff = nowEpoch - authTimeEpoch;
                if (diff > request.Client.UserSsoLifetime.Value)
                {
                    Logger.LogInformation("Showing login: User's auth session duration: {sessionDuration} exceeds client's user SSO lifetime: {userSsoLifetime}.", diff, request.Client.UserSsoLifetime);
                    return(new InteractionResponse {
                        IsLogin = true
                    });
                }
            }

            return(new InteractionResponse());
        }
コード例 #21
0
 public async Task IsActiveAsync(IsActiveContext context)
 {
 }
コード例 #22
0
        /// <summary>
        /// Validates a refresh token
        /// </summary>
        /// <param name="tokenHandle">The token handle.</param>
        /// <param name="client">The client.</param>
        /// <returns></returns>
        public virtual async Task <TokenValidationResult> ValidateRefreshTokenAsync(string tokenHandle, Client client)
        {
            var invalidGrant = new TokenValidationResult
            {
                IsError = true, Error = OidcConstants.TokenErrors.InvalidGrant
            };

            Logger.LogTrace("Start refresh token validation");

            /////////////////////////////////////////////
            // check if refresh token is valid
            /////////////////////////////////////////////
            var refreshToken = await RefreshTokenStore.GetRefreshTokenAsync(tokenHandle);

            if (refreshToken == null)
            {
                Logger.LogWarning("Invalid refresh token");
                return(invalidGrant);
            }

            /////////////////////////////////////////////
            // check if refresh token has expired
            /////////////////////////////////////////////
            if (refreshToken.CreationTime.HasExceeded(refreshToken.Lifetime, Clock.UtcNow.DateTime))
            {
                Logger.LogWarning("Refresh token has expired.");
                return(invalidGrant);
            }

            /////////////////////////////////////////////
            // check if client belongs to requested refresh token
            /////////////////////////////////////////////
            if (client.ClientId != refreshToken.ClientId)
            {
                Logger.LogError("{0} tries to refresh token belonging to {1}", client.ClientId, refreshToken.ClientId);
                return(invalidGrant);
            }

            /////////////////////////////////////////////
            // check if client still has offline_access scope
            /////////////////////////////////////////////
            if (!client.AllowOfflineAccess)
            {
                Logger.LogError("{clientId} does not have access to offline_access scope anymore", client.ClientId);
                return(invalidGrant);
            }

            /////////////////////////////////////////////
            // check if refresh token has been consumed
            /////////////////////////////////////////////
            if (refreshToken.ConsumedTime.HasValue)
            {
                if ((await AcceptConsumedTokenAsync(refreshToken)) == false)
                {
                    Logger.LogWarning("Rejecting refresh token because it has been consumed already.");
                    return(invalidGrant);
                }
            }

            /////////////////////////////////////////////
            // make sure user is enabled
            /////////////////////////////////////////////
            var isActiveCtx = new IsActiveContext(
                refreshToken.Subject,
                client,
                IdentityServerConstants.ProfileIsActiveCallers.RefreshTokenValidation);

            await Profile.IsActiveAsync(isActiveCtx);

            if (isActiveCtx.IsActive == false)
            {
                Logger.LogError("{subjectId} has been disabled", refreshToken.Subject.GetSubjectId());
                return(invalidGrant);
            }

            return(new TokenValidationResult
            {
                IsError = false,
                RefreshToken = refreshToken,
                Client = client
            });
        }
コード例 #23
0
        public async Task IsActiveAsync(IsActiveContext context)
        {
            var user = await UserStore.FindBySubjectIdAsync(context.Subject.GetSubjectId());

            context.IsActive = user != null;
        }
コード例 #24
0
 public Task IsActiveAsync(IsActiveContext context)
 {
     // here we should check if the user is active
     context.IsActive = true;
     return(Task.FromResult(0));
 }
コード例 #25
0
        private async Task <TokenRequestValidationResult> ValidateAuthorizationCodeRequestAsync(NameValueCollection parameters)
        {
            Logger.Info("Start validation of authorization code token request");

            /////////////////////////////////////////////
            // check if client is authorized for grant type
            /////////////////////////////////////////////
            if (_validatedRequest.Client.Flow != Flows.AuthorizationCode &&
                _validatedRequest.Client.Flow != Flows.Hybrid)
            {
                LogError("Client not authorized for code flow");
                return(Invalid(Constants.TokenErrors.UnauthorizedClient));
            }

            /////////////////////////////////////////////
            // validate authorization code
            /////////////////////////////////////////////
            var code = parameters.Get(Constants.TokenRequest.Code);

            if (code.IsMissing())
            {
                var error = "Authorization code is missing.";
                LogError(error);
                await RaiseFailedAuthorizationCodeRedeemedEventAsync(null, error);

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            _validatedRequest.AuthorizationCodeHandle = code;

            var authZcode = await _authorizationCodes.GetAsync(code);

            if (authZcode == null)
            {
                LogError("Invalid authorization code: " + code);
                await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, "Invalid handle");

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            await _authorizationCodes.RemoveAsync(code);

            /////////////////////////////////////////////
            // validate client binding
            /////////////////////////////////////////////
            if (authZcode.Client.ClientId != _validatedRequest.Client.ClientId)
            {
                LogError(string.Format("Client {0} is trying to use a code from client {1}", _validatedRequest.Client.ClientId, authZcode.Client.ClientId));
                await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, "Invalid client binding");

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // validate code expiration
            /////////////////////////////////////////////
            if (authZcode.CreationTime.HasExceeded(_validatedRequest.Client.AuthorizationCodeLifetime))
            {
                var error = "Authorization code is expired";
                LogError(error);
                await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error);

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            _validatedRequest.AuthorizationCode = authZcode;

            /////////////////////////////////////////////
            // validate redirect_uri
            /////////////////////////////////////////////
            var redirectUri = parameters.Get(Constants.TokenRequest.RedirectUri);

            if (redirectUri.IsMissing())
            {
                var error = "Redirect URI is missing.";
                LogError(error);
                await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error);

                return(Invalid(Constants.TokenErrors.UnauthorizedClient));
            }

            if (redirectUri.Equals(_validatedRequest.AuthorizationCode.RedirectUri, StringComparison.Ordinal) == false)
            {
                var error = "Invalid redirect_uri: " + redirectUri;
                LogError(error);
                await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error);

                return(Invalid(Constants.TokenErrors.UnauthorizedClient));
            }

            /////////////////////////////////////////////
            // validate scopes are present
            /////////////////////////////////////////////
            if (_validatedRequest.AuthorizationCode.RequestedScopes == null ||
                !_validatedRequest.AuthorizationCode.RequestedScopes.Any())
            {
                var error = "Authorization code has no associated scopes.";
                LogError(error);
                await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error);

                return(Invalid(Constants.TokenErrors.InvalidRequest));
            }


            /////////////////////////////////////////////
            // make sure user is enabled
            /////////////////////////////////////////////
            var isActiveCtx = new IsActiveContext(_validatedRequest.AuthorizationCode.Subject, _validatedRequest.Client);
            await _users.IsActiveAsync(isActiveCtx);

            if (isActiveCtx.IsActive == false)
            {
                var error = "User has been disabled: " + _validatedRequest.AuthorizationCode.Subject;
                LogError(error);
                await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error);

                return(Invalid(Constants.TokenErrors.InvalidRequest));
            }

            Logger.Info("Validation of authorization code token request success");
            await RaiseSuccessfulAuthorizationCodeRedeemedEventAsync();

            return(Valid());
        }
コード例 #26
0
        public async Task IsActiveAsync(IsActiveContext context)
        {
            CustomIdentityUser user = await _userManager.GetUserAsync(context.Subject);

            context.IsActive = (user != null) && user.IsActive;
        }
コード例 #27
0
 public Task IsActiveAsync(IsActiveContext context)
 {
     return(Task.FromResult(0));
 }
コード例 #28
0
 /// <summary>
 /// Determines if the user is active.
 /// </summary>
 /// <param name="context"></param>
 /// <param name="user"></param>
 /// <returns></returns>
 protected virtual async Task IsActiveAsync(IsActiveContext context, ApplicationUser user)
 {
     context.IsActive = await IsUserActiveAsync(user);
 }
コード例 #29
0
ファイル: ProfileService.cs プロジェクト: RaduGitHub/Covfefe
 public Task IsActiveAsync(IsActiveContext context)
 {
     return(Task.CompletedTask);
 }
コード例 #30
0
        public Task IsActiveAsync(IsActiveContext context)
        {
            context.IsActive = true;

            return(Task.CompletedTask);
        }
 public async Task IsActiveAsync(IsActiveContext context)
 {
     var sub = context.Subject.GetSubjectId();
     var user = await _userManager.FindByIdAsync(sub);
     context.IsActive = user != null;
 }
コード例 #32
0
        private async Task <TokenRequestValidationResult> ValidateRefreshTokenRequestAsync(NameValueCollection parameters)
        {
            _logger.LogDebug("Start validation of refresh token request");

            var refreshTokenHandle = parameters.Get(OidcConstants.TokenRequest.RefreshToken);

            if (refreshTokenHandle.IsMissing())
            {
                var error = "Refresh token is missing";
                LogError(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(null, error);

                return(Invalid(OidcConstants.TokenErrors.InvalidRequest));
            }

            if (refreshTokenHandle.Length > _options.InputLengthRestrictions.RefreshToken)
            {
                var error = "Refresh token too long";
                LogError(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(null, error);

                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            _validatedRequest.RefreshTokenHandle = refreshTokenHandle;

            /////////////////////////////////////////////
            // check if refresh token is valid
            /////////////////////////////////////////////
            var refreshToken = await _refreshTokenStore.GetRefreshTokenAsync(refreshTokenHandle);

            if (refreshToken == null)
            {
                LogError("Refresh token cannot be found in store: {refreshToken}", refreshTokenHandle);
                var error = "Refresh token cannot be found in store: " + refreshTokenHandle;
                await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // check if refresh token has expired
            /////////////////////////////////////////////
            if (refreshToken.CreationTime.HasExceeded(refreshToken.Lifetime))
            {
                var error = "Refresh token has expired";
                LogError(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                await _refreshTokenStore.RemoveRefreshTokenAsync(refreshTokenHandle);

                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // check if client belongs to requested refresh token
            /////////////////////////////////////////////
            if (_validatedRequest.Client.ClientId != refreshToken.ClientId)
            {
                LogError("{0} tries to refresh token belonging to {1}", _validatedRequest.Client.ClientId, refreshToken.ClientId);
                await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, "Invalid client binding");

                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // check if client still has offline_access scope
            /////////////////////////////////////////////
            if (!_validatedRequest.Client.AllowOfflineAccess)
            {
                LogError("{clientId} does not have access to offline_access scope anymore", _validatedRequest.Client.ClientId);
                var error = "Client does not have access to offline_access scope anymore";
                await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            _validatedRequest.RefreshToken = refreshToken;

            /////////////////////////////////////////////
            // make sure user is enabled
            /////////////////////////////////////////////
            var subject     = _validatedRequest.RefreshToken.Subject;
            var isActiveCtx = new IsActiveContext(subject, _validatedRequest.Client, IdentityServerConstants.ProfileIsActiveCallers.RefreshTokenValidation);
            await _profile.IsActiveAsync(isActiveCtx);

            if (isActiveCtx.IsActive == false)
            {
                LogError("{subjectId} has been disabled", _validatedRequest.RefreshToken.SubjectId);
                var error = "User has been disabled: " + _validatedRequest.RefreshToken.SubjectId;
                await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            _validatedRequest.Subject = subject;

            _logger.LogDebug("Validation of refresh token request success");
            return(Valid());
        }