예제 #1
0
    public async Task IsRedirectUriValidAsync()
    {
        (await _abpStrictRedirectUriValidator.IsRedirectUriValidAsync("https://t1.api.abp.io:8080/signin-oidc", _testClient)).ShouldBeTrue();
        (await _abpStrictRedirectUriValidator.IsRedirectUriValidAsync("https://api.abp.io:8080/signin-oidc", _testClient)).ShouldBeTrue();
        (await _abpStrictRedirectUriValidator.IsRedirectUriValidAsync("http://t2.ng.abp.io/index.html", _testClient)).ShouldBeTrue();
        (await _abpStrictRedirectUriValidator.IsRedirectUriValidAsync("http://ng.abp.io/index.html", _testClient)).ShouldBeTrue();

        (await _abpStrictRedirectUriValidator.IsRedirectUriValidAsync("https://api.abp:8080/", _testClient)).ShouldBeFalse();
        (await _abpStrictRedirectUriValidator.IsRedirectUriValidAsync("http://ng.abp.io", _testClient)).ShouldBeTrue();
        (await _abpStrictRedirectUriValidator.IsRedirectUriValidAsync("https://api.t1.abp:8080/", _testClient)).ShouldBeFalse();
        (await _abpStrictRedirectUriValidator.IsRedirectUriValidAsync("http://ng.t1.abp.io", _testClient)).ShouldBeFalse();
        (await _abpStrictRedirectUriValidator.IsRedirectUriValidAsync("http://t1.ng.abp.io/index.html.mydomain.com", _testClient)).ShouldBeFalse();
    }
        public async Task<AuthorizeRequestValidationResult> ValidateClientAsync(ValidatedAuthorizeRequest request)
        {
            //////////////////////////////////////////////////////////
            // client_id must be present
            /////////////////////////////////////////////////////////
            var clientId = request.Raw.Get(Constants.AuthorizeRequest.ClientId);
            if (clientId.IsMissingOrTooLong(_options.InputLengthRestrictions.ClientId))
            {
                LogError("client_id is missing or too long", request);
                return Invalid(request);
            }

            request.ClientId = clientId;


            //////////////////////////////////////////////////////////
            // redirect_uri must be present, and a valid uri
            //////////////////////////////////////////////////////////
            var redirectUri = request.Raw.Get(Constants.AuthorizeRequest.RedirectUri);

            if (redirectUri.IsMissingOrTooLong(_options.InputLengthRestrictions.RedirectUri))
            {
                LogError("redirect_uri is missing or too long", request);
                return Invalid(request);
            }

            Uri uri;
            if (!Uri.TryCreate(redirectUri, UriKind.Absolute, out uri))
            {
                LogError("invalid redirect_uri: " + redirectUri, request);
                return Invalid(request);
            }

            request.RedirectUri = redirectUri;


            //////////////////////////////////////////////////////////
            // check for valid client
            //////////////////////////////////////////////////////////
            var client = await _clients.FindClientByIdAsync(request.ClientId);
            if (client == null || client.Enabled == false)
            {
                LogError("Unknown client or not enabled: " + request.ClientId, request);
                return Invalid(request, ErrorTypes.User, Constants.AuthorizeErrors.UnauthorizedClient);
            }

            request.Client = client;

            //////////////////////////////////////////////////////////
            // check if redirect_uri is valid
            //////////////////////////////////////////////////////////
            if (await _uriValidator.IsRedirectUriValidAsync(request.RedirectUri, request.Client) == false)
            {
                LogError("Invalid redirect_uri: " + request.RedirectUri, request);
                return Invalid(request, ErrorTypes.User, Constants.AuthorizeErrors.UnauthorizedClient);
            }

            return Valid(request);
        }
        private async Task <AuthorizeRequestValidationResult> ValidateClientAsync(ValidatedAuthorizeRequest request)
        {
            //////////////////////////////////////////////////////////
            // check request object requirement
            //////////////////////////////////////////////////////////
            if (request.Client.RequireRequestObject)
            {
                if (!request.RequestObjectValues.Any())
                {
                    return(Invalid(request, description: "Client must use request object, but no request or request_uri parameter present"));
                }
            }

            //////////////////////////////////////////////////////////
            // redirect_uri must be present, and a valid uri
            //////////////////////////////////////////////////////////
            var redirectUri = request.Raw.Get(OidcConstants.AuthorizeRequest.RedirectUri);

            if (redirectUri.IsMissingOrTooLong(_options.InputLengthRestrictions.RedirectUri))
            {
                LogError("redirect_uri is missing or too long", request);
                return(Invalid(request, description: "Invalid redirect_uri"));
            }

            if (!Uri.TryCreate(redirectUri, UriKind.Absolute, out _))
            {
                LogError("malformed redirect_uri", redirectUri, request);
                return(Invalid(request, description: "Invalid redirect_uri"));
            }

            //////////////////////////////////////////////////////////
            // check if client protocol type is oidc
            //////////////////////////////////////////////////////////
            if (request.Client.ProtocolType != IdentityServerConstants.ProtocolTypes.OpenIdConnect)
            {
                LogError("Invalid protocol type for OIDC authorize endpoint", request.Client.ProtocolType, request);
                return(Invalid(request, OidcConstants.AuthorizeErrors.UnauthorizedClient, description: "Invalid protocol"));
            }

            //////////////////////////////////////////////////////////
            // check if redirect_uri is valid
            //////////////////////////////////////////////////////////
            if (await _uriValidator.IsRedirectUriValidAsync(redirectUri, request.Client) == false)
            {
                LogError("Invalid redirect_uri", redirectUri, request);
                return(Invalid(request, OidcConstants.AuthorizeErrors.InvalidRequest, "Invalid redirect_uri"));
            }

            request.RedirectUri = redirectUri;

            return(Valid(request));
        }
        private async Task <AuthorizeRequestValidationResult> ValidateClientAsync(ValidatedAuthorizeRequest request)
        {
            //////////////////////////////////////////////////////////
            // client_id must be present
            /////////////////////////////////////////////////////////
            var clientId = request.Raw.Get(OidcConstants.AuthorizeRequest.ClientId);

            if (clientId.IsMissingOrTooLong(_options.InputLengthRestrictions.ClientId))
            {
                LogError("client_id is missing or too long", request);
                return(Invalid(request, description: "Invalid client_id"));
            }

            request.ClientId = clientId;


            //////////////////////////////////////////////////////////
            // redirect_uri must be present, and a valid uri
            //////////////////////////////////////////////////////////
            var redirectUri = request.Raw.Get(OidcConstants.AuthorizeRequest.RedirectUri);

            if (redirectUri.IsMissingOrTooLong(_options.InputLengthRestrictions.RedirectUri))
            {
                LogError("redirect_uri is missing or too long", request);
                return(Invalid(request, description: "Invalid redirect_uri"));
            }

            if (!Uri.TryCreate(redirectUri, UriKind.Absolute, out var _))
            {
                LogError("malformed redirect_uri", redirectUri, request);
                return(Invalid(request, description: "Invalid redirect_uri"));
            }

            //////////////////////////////////////////////////////////
            // check for valid client
            //////////////////////////////////////////////////////////
            var client = await _clients.FindEnabledClientByIdAsync(request.ClientId);

            if (client == null)
            {
                LogError("Unknown client or not enabled", request.ClientId, request);
                return(Invalid(request, OidcConstants.AuthorizeErrors.UnauthorizedClient));
            }

            request.SetClient(client);

            //////////////////////////////////////////////////////////
            // check if client protocol type is oidc
            //////////////////////////////////////////////////////////
            if (request.Client.ProtocolType != IdentityServerConstants.ProtocolTypes.OpenIdConnect)
            {
                LogError("Invalid protocol type for OIDC authorize endpoint", request.Client.ProtocolType, request);
                return(Invalid(request, OidcConstants.AuthorizeErrors.UnauthorizedClient, description: "Invalid protocol"));
            }

            //////////////////////////////////////////////////////////
            // check if redirect_uri is valid
            //////////////////////////////////////////////////////////
            if (await _uriValidator.IsRedirectUriValidAsync(redirectUri, request.Client) == false)
            {
                LogError("Invalid redirect_uri", redirectUri, request);
                return(Invalid(request, OidcConstants.AuthorizeErrors.UnauthorizedClient, "Invalid redirect_uri"));
            }

            request.RedirectUri = redirectUri;

            return(Valid(request));
        }
        public async Task <ValidationResult> ValidateClientAsync()
        {
            Logger.Info("Start authorize request client validation");

            if (_validatedRequest.ClientId.IsMissing())
            {
                throw new InvalidOperationException("ClientId is empty. Validate protocol first.");
            }

            //////////////////////////////////////////////////////////
            // check for valid client
            //////////////////////////////////////////////////////////
            var client = await _clients.FindClientByIdAsync(_validatedRequest.ClientId);

            if (client == null || client.Enabled == false)
            {
                LogError("Unknown client or not enabled: " + _validatedRequest.ClientId);
                return(Invalid(ErrorTypes.User, Constants.AuthorizeErrors.UnauthorizedClient));
            }

            _validatedRequest.Client = client;

            //////////////////////////////////////////////////////////
            // check if redirect_uri is valid
            //////////////////////////////////////////////////////////
            if (await _uriValidator.IsRedirectUriValidAsync(_validatedRequest.RedirectUri, _validatedRequest.Client) == false)
            {
                LogError("Invalid redirect_uri: " + _validatedRequest.RedirectUri);
                return(Invalid(ErrorTypes.User, Constants.AuthorizeErrors.UnauthorizedClient));
            }

            //////////////////////////////////////////////////////////
            // check if flow is allowed for client
            //////////////////////////////////////////////////////////
            if (_validatedRequest.Flow != _validatedRequest.Client.Flow)
            {
                LogError("Invalid flow for client: " + _validatedRequest.Flow);
                return(Invalid(ErrorTypes.User, Constants.AuthorizeErrors.UnauthorizedClient));
            }

            //////////////////////////////////////////////////////////
            // check if scopes are valid/supported and check for resource scopes
            //////////////////////////////////////////////////////////
            if (await _scopeValidator.AreScopesValidAsync(_validatedRequest.RequestedScopes) == false)
            {
                return(Invalid(ErrorTypes.Client, Constants.AuthorizeErrors.InvalidScope));
            }

            if (_scopeValidator.ContainsOpenIdScopes && !_validatedRequest.IsOpenIdRequest)
            {
                LogError("Identity related scope requests, but no openid scope");
                return(Invalid(ErrorTypes.Client, Constants.AuthorizeErrors.InvalidScope));
            }

            if (_scopeValidator.ContainsResourceScopes)
            {
                _validatedRequest.IsResourceRequest = true;
            }

            //////////////////////////////////////////////////////////
            // check scopes and scope restrictions
            //////////////////////////////////////////////////////////
            if (!_scopeValidator.AreScopesAllowed(_validatedRequest.Client, _validatedRequest.RequestedScopes))
            {
                return(Invalid(ErrorTypes.User, Constants.AuthorizeErrors.UnauthorizedClient));
            }

            _validatedRequest.ValidatedScopes = _scopeValidator;

            //////////////////////////////////////////////////////////
            // check id vs resource scopes and response types plausability
            //////////////////////////////////////////////////////////
            if (!_scopeValidator.IsResponseTypeValid(_validatedRequest.ResponseType))
            {
                return(Invalid(ErrorTypes.Client, Constants.AuthorizeErrors.InvalidScope));
            }

            //////////////////////////////////////////////////////////
            // check if sessionId is available and if session management is enabled
            //////////////////////////////////////////////////////////
            if (_options.Endpoints.EnableCheckSessionEndpoint)
            {
                if (_validatedRequest.SessionId.IsMissing())
                {
                    Logger.Warn("Session management is enabled, but session id cookie is missing.");
                }
            }

            var customResult = await _customValidator.ValidateAuthorizeRequestAsync(_validatedRequest);

            if (customResult.IsError)
            {
                LogError("Error in custom validation: " + customResult.Error);
            }
            else
            {
                LogSuccess();
            }

            return(customResult);
        }