예제 #1
0
        /// <summary>
        /// Try to get the client id.
        /// </summary>
        /// <param name="instruction"></param>
        /// <returns></returns>
        public string GetClientId(AuthenticateInstruction instruction)
        {
            if (instruction.ClientAssertionType != Dtos.Constants.ClientAssertionTypes.JwtBearer || string.IsNullOrWhiteSpace(instruction.ClientAssertion))
            {
                return(string.Empty);
            }

            var clientAssertion = instruction.ClientAssertion;
            var isJweToken      = _jwtParser.IsJweToken(clientAssertion);
            var isJwsToken      = _jwtParser.IsJwsToken(clientAssertion);

            if (isJweToken && isJwsToken)
            {
                return(string.Empty);
            }

            // It's a JWE token then return the client_id from the HTTP body
            if (isJweToken)
            {
                return(instruction.ClientIdFromHttpRequestBody);
            }

            // It's a JWS token then return the client_id from the token.
            var payload = _jwsParser.GetPayload(clientAssertion);

            if (payload == null)
            {
                return(string.Empty);
            }

            return(payload.Issuer);
        }
예제 #2
0
        public string GetClientIdFromClientAssertion(AuthenticateInstruction instruction)
        {
            if (instruction.ClientAssertionType != "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" || string.IsNullOrWhiteSpace(instruction.ClientAssertion))
            {
                return(string.Empty);
            }

            var clientAssertion = instruction.ClientAssertion;
            var isJweToken      = _jwtParser.IsJweToken(clientAssertion);
            var isJwsToken      = _jwtParser.IsJwsToken(clientAssertion);

            if (isJweToken && isJwsToken)
            {
                return(string.Empty);
            }

            if (isJweToken)
            {
                return(instruction.ClientIdFromHttpRequestBody);
            }

            var payload = _jwsGenerator.ExtractPayload(clientAssertion);

            if (payload == null)
            {
                return(string.Empty);
            }

            return(payload.GetClaimValue("iss"));
        }
        public async Task <bool> Handle(AuthenticateInstruction authenticateInstruction, OAuthClient client, string expectedIssuer)
        {
            if (authenticateInstruction == null)
            {
                throw new ArgumentNullException(nameof(authenticateInstruction));
            }

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

            if (client.Secrets == null)
            {
                throw new ArgumentNullException(nameof(client.Secrets));
            }

            var clientSecret = client.Secrets.FirstOrDefault(s => s.Type == ClientSecretTypes.SharedSecret);

            if (clientSecret == null)
            {
                throw new OAuthException(ErrorCodes.INVALID_CLIENT_AUTH, ErrorMessages.NO_CLIENT_SECRET);
            }

            var clientAssertion = authenticateInstruction.ClientAssertion;
            var isJweToken      = _jwtParser.IsJweToken(clientAssertion);

            if (!isJweToken)
            {
                throw new OAuthException(ErrorCodes.INVALID_CLIENT_AUTH, ErrorMessages.BAD_CLIENT_ASSERTION_FORMAT);
            }

            var clientId = authenticateInstruction.ClientIdFromHttpRequestBody;
            var jws      = await _jwtParser.Decrypt(clientAssertion, clientId, clientSecret.Value).ConfigureAwait(false);

            if (string.IsNullOrWhiteSpace(jws))
            {
                throw new OAuthException(ErrorCodes.INVALID_CLIENT_AUTH, ErrorMessages.BAD_CLIENT_ASSERTION_DECRYPTION);
            }

            var isJwsToken = _jwtParser.IsJwsToken(jws);

            if (!isJwsToken)
            {
                throw new OAuthException(ErrorCodes.INVALID_CLIENT_AUTH, ErrorMessages.BAD_CLIENT_ASSERTION_FORMAT);
            }

            var payload = await _jwtParser.Unsign(clientAssertion, clientId).ConfigureAwait(false);

            if (payload == null)
            {
                throw new OAuthException(ErrorCodes.INVALID_CLIENT_AUTH, ErrorMessages.BAD_CLIENT_ASSERTION_SIGNATURE);
            }

            return(ValidateJwsPayLoad(payload, expectedIssuer));
        }
        protected async Task <JwsPayload> ExtractHint(string tokenHint, CancellationToken cancellationToken)
        {
            if (!_jwtParser.IsJwsToken(tokenHint) && !_jwtParser.IsJweToken(tokenHint))
            {
                throw new OAuthException(ErrorCodes.INVALID_REQUEST, ErrorMessages.INVALID_IDTOKENHINT);
            }

            if (_jwtParser.IsJweToken(tokenHint))
            {
                tokenHint = await _jwtParser.Decrypt(tokenHint, cancellationToken);

                if (string.IsNullOrWhiteSpace(tokenHint))
                {
                    throw new OAuthException(ErrorCodes.INVALID_REQUEST, ErrorMessages.INVALID_IDTOKENHINT);
                }
            }

            return(await _jwtParser.Unsign(tokenHint, cancellationToken));
        }
예제 #5
0
        public virtual async Task <RequestObjectValidatorResult> Validate(string request, BaseClient oauthClient, CancellationToken cancellationToken, string errorCode = ErrorCodes.INVALID_REQUEST_OBJECT)
        {
            if (!_jwtParser.IsJwsToken(request) && !_jwtParser.IsJweToken(request))
            {
                throw new OAuthException(errorCode, ErrorMessages.INVALID_REQUEST_PARAMETER);
            }

            var jws = request;

            if (_jwtParser.IsJweToken(request))
            {
                jws = await _jwtParser.Decrypt(jws, cancellationToken);

                if (string.IsNullOrWhiteSpace(jws))
                {
                    throw new OAuthException(errorCode, ErrorMessages.INVALID_JWE_REQUEST_PARAMETER);
                }
            }

            JwsHeader header = null;

            try
            {
                header = _jwtParser.ExtractJwsHeader(jws);
            }
            catch (InvalidOperationException)
            {
                throw new OAuthException(errorCode, ErrorMessages.INVALID_JWS_REQUEST_PARAMETER);
            }

            JwsPayload jwsPayload;

            try
            {
                jwsPayload = await _jwtParser.Unsign(jws, oauthClient, errorCode);
            }
            catch (JwtException ex)
            {
                throw new OAuthException(errorCode, ex.Message);
            }

            return(new RequestObjectValidatorResult(jwsPayload, header));
        }
예제 #6
0
        private async Task <AuthorizationRequest> GetAuthorizationRequestFromJwt(string token, string clientId)
        {
            var jwsToken = token;

            if (_jwtParser.IsJweToken(token))
            {
                jwsToken = await _jwtParser.DecryptAsync(token, clientId);
            }

            var jwsPayload = await _jwtParser.UnSignAsync(jwsToken, clientId);

            return(jwsPayload == null ? null : jwsPayload.ToAuthorizationRequest());
        }
        public async Task <bool> Handle(AuthenticateInstruction authenticateInstruction, BaseClient client, string expectedIssuer, CancellationToken cancellationToken, string errorCode = ErrorCodes.INVALID_CLIENT)
        {
            if (authenticateInstruction == null)
            {
                throw new ArgumentNullException(nameof(authenticateInstruction));
            }

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

            if (string.IsNullOrWhiteSpace(client.ClientSecret))
            {
                throw new OAuthException(errorCode, ErrorMessages.NO_CLIENT_SECRET);
            }

            var clientAssertion = authenticateInstruction.ClientAssertion;
            var isJweToken      = _jwtParser.IsJweToken(clientAssertion);

            if (!isJweToken)
            {
                throw new OAuthException(errorCode, ErrorMessages.BAD_CLIENT_ASSERTION_FORMAT);
            }

            var clientId = authenticateInstruction.ClientIdFromHttpRequestBody;
            var jws      = await _jwtParser.Decrypt(clientAssertion, clientId, client.ClientSecret, cancellationToken);

            if (string.IsNullOrWhiteSpace(jws))
            {
                throw new OAuthException(errorCode, ErrorMessages.BAD_CLIENT_ASSERTION_DECRYPTION);
            }

            var isJwsToken = _jwtParser.IsJwsToken(jws);

            if (!isJwsToken)
            {
                throw new OAuthException(errorCode, ErrorMessages.BAD_CLIENT_ASSERTION_FORMAT);
            }

            JwsPayload payload = await _jwtParser.Unsign(clientAssertion, clientId, cancellationToken, errorCode);

            if (payload == null)
            {
                throw new OAuthException(errorCode, ErrorMessages.BAD_CLIENT_ASSERTION_SIGNATURE);
            }

            return(ValidateJwsPayLoad(payload, expectedIssuer, errorCode));
        }
예제 #8
0
        private async Task <JwsPayload> Extract(string accessToken)
        {
            var isJwe = _jwtParser.IsJweToken(accessToken);
            var isJws = _jwtParser.IsJwsToken(accessToken);

            if (!isJwe && !isJws)
            {
                return(null);
            }

            var jws = accessToken;

            if (isJwe)
            {
                jws = await _jwtParser.Decrypt(accessToken);
            }

            return(await _jwtParser.Unsign(jws));
        }
        private async Task <JwsPayload> ExtractPATTokenPayload(CancellationToken cancellationToken)
        {
            var token = ExtractAuthorizationValue();

            if (string.IsNullOrWhiteSpace(token))
            {
                return(null);
            }

            var isJweToken = _jwtParser.IsJweToken(token);
            var isJwsToken = _jwtParser.IsJwsToken(token);

            if (isJweToken && isJwsToken)
            {
                return(null);
            }

            if (isJweToken)
            {
                token = await _jwtParser.Decrypt(token, cancellationToken);
            }

            return(await _jwtParser.Unsign(token, cancellationToken));
        }
예제 #10
0
        protected async Task <bool> CheckRequest(HandlerContext context, string request)
        {
            var openidClient = (OpenIdClient)context.Client;

            if (!_jwtParser.IsJwsToken(request) && !_jwtParser.IsJweToken(request))
            {
                throw new OAuthException(ErrorCodes.INVALID_REQUEST, ErrorMessages.INVALID_REQUEST_PARAMETER);
            }

            var jws = request;

            if (_jwtParser.IsJweToken(request))
            {
                jws = await _jwtParser.Decrypt(jws);

                if (string.IsNullOrWhiteSpace(jws))
                {
                    throw new OAuthException(ErrorCodes.INVALID_REQUEST, ErrorMessages.INVALID_JWE_REQUEST_PARAMETER);
                }
            }

            JwsHeader header = null;

            try
            {
                header = _jwtParser.ExtractJwsHeader(jws);
            }
            catch (InvalidOperationException)
            {
                throw new OAuthException(ErrorCodes.INVALID_REQUEST, ErrorMessages.INVALID_JWS_REQUEST_PARAMETER);
            }

            if (
                (!string.IsNullOrWhiteSpace(openidClient.RequestObjectSigningAlg) && header.Alg != openidClient.RequestObjectSigningAlg) ||
                (string.IsNullOrWhiteSpace(openidClient.RequestObjectSigningAlg) && header.Alg != NoneSignHandler.ALG_NAME)
                )
            {
                throw new OAuthException(ErrorCodes.INVALID_REQUEST, ErrorMessages.INVALID_SIGNATURE_ALG);
            }

            var jwsPayload = await _jwtParser.Unsign(jws, context.Client);

            if (jwsPayload == null)
            {
                throw new OAuthException(ErrorCodes.INVALID_REQUEST, ErrorMessages.INVALID_JWS_REQUEST_PARAMETER);
            }

            if (!jwsPayload.ContainsKey(OAuth.DTOs.AuthorizationRequestParameters.ResponseType))
            {
                throw new OAuthException(ErrorCodes.INVALID_REQUEST, ErrorMessages.MISSING_RESPONSE_TYPE_CLAIM);
            }

            if (!jwsPayload.ContainsKey(OAuth.DTOs.AuthorizationRequestParameters.ClientId))
            {
                throw new OAuthException(ErrorCodes.INVALID_REQUEST, ErrorMessages.MISSING_CLIENT_ID_CLAIM);
            }

            if (!jwsPayload[OAuth.DTOs.AuthorizationRequestParameters.ResponseType].ToString().Split(' ').OrderBy(s => s).SequenceEqual(context.Request.Data.GetResponseTypesFromAuthorizationRequest()))
            {
                throw new OAuthException(ErrorCodes.INVALID_REQUEST, ErrorMessages.INVALID_RESPONSE_TYPE_CLAIM);
            }

            if (jwsPayload[OAuth.DTOs.AuthorizationRequestParameters.ClientId].ToString() != context.Client.ClientId)
            {
                throw new OAuthException(ErrorCodes.INVALID_REQUEST, ErrorMessages.INVALID_CLIENT_ID_CLAIM);
            }

            context.Request.SetData(JObject.FromObject(jwsPayload));
            return(true);
        }
        private async Task ProcessIdTokenHint(
            ActionResult actionResult,
            AuthorizationParameter authorizationParameter,
            ICollection <PromptParameter> prompts,
            ClaimsPrincipal claimsPrincipal,
            string issuerName)
        {
            if (!string.IsNullOrWhiteSpace(authorizationParameter.IdTokenHint) &&
                prompts.Contains(PromptParameter.none) &&
                actionResult.Type == TypeActionResult.RedirectToCallBackUrl)
            {
                var token = authorizationParameter.IdTokenHint;
                if (!_jwtParser.IsJweToken(token) &&
                    !_jwtParser.IsJwsToken(token))
                {
                    throw new IdentityServerExceptionWithState(
                              ErrorCodes.InvalidRequestCode,
                              ErrorDescriptions.TheIdTokenHintParameterIsNotAValidToken,
                              authorizationParameter.State);
                }

                string jwsToken;
                if (_jwtParser.IsJweToken(token))
                {
                    jwsToken = await _jwtParser.DecryptAsync(token);

                    if (string.IsNullOrWhiteSpace(jwsToken))
                    {
                        throw new IdentityServerExceptionWithState(
                                  ErrorCodes.InvalidRequestCode,
                                  ErrorDescriptions.TheIdTokenHintParameterCannotBeDecrypted,
                                  authorizationParameter.State);
                    }
                }
                else
                {
                    jwsToken = token;
                }

                var jwsPayload = await _jwtParser.UnSignAsync(jwsToken);

                if (jwsPayload == null)
                {
                    throw new IdentityServerExceptionWithState(
                              ErrorCodes.InvalidRequestCode,
                              ErrorDescriptions.TheSignatureOfIdTokenHintParameterCannotBeChecked,
                              authorizationParameter.State);
                }

                if (jwsPayload.Audiences == null ||
                    !jwsPayload.Audiences.Any() ||
                    !jwsPayload.Audiences.Contains(issuerName))
                {
                    throw new IdentityServerExceptionWithState(
                              ErrorCodes.InvalidRequestCode,
                              ErrorDescriptions.TheIdentityTokenDoesntContainSimpleIdentityServerAsAudience,
                              authorizationParameter.State);
                }

                var currentSubject  = string.Empty;
                var expectedSubject = jwsPayload.GetClaimValue(Jwt.Constants.StandardResourceOwnerClaimNames.Subject);
                if (claimsPrincipal != null && claimsPrincipal.IsAuthenticated())
                {
                    currentSubject = claimsPrincipal.GetSubject();
                }

                if (currentSubject != expectedSubject)
                {
                    throw new IdentityServerExceptionWithState(
                              ErrorCodes.InvalidRequestCode,
                              ErrorDescriptions.TheCurrentAuthenticatedUserDoesntMatchWithTheIdentityToken,
                              authorizationParameter.State);
                }
            }
        }