예제 #1
0
        /// <summary>
        /// Deserialize and verify the authentication ticket.
        /// </summary>
        /// <param name="ticket">The serialized ticket.</param>
        /// <returns>The authentication ticket.</returns>
        public Task <AuthenticationTicket> DeserializeTicketAsync(string ticket)
        {
            var handler = SecurityTokenHandler as ISecurityTokenValidator;

            if (handler == null)
            {
                return(Task.FromResult(DataFormat?.Unprotect(ticket)));
            }

            // Create new validation parameters to validate the security token.
            // ValidateAudience and ValidateLifetime are always set to false:
            // if necessary, the audience and the expiration can be validated
            // in InvokeValidationEndpointAsync or InvokeTokenEndpointAsync.
            var parameters = new TokenValidationParameters {
                IssuerSigningKey = SigningCredentials.SigningKey,
                ValidIssuer      = Issuer,
                ValidateAudience = false,
                ValidateLifetime = false
            };

            SecurityToken token;
            var           principal = handler.ValidateToken(ticket, parameters, out token);

            // Parameters stored in AuthenticationProperties are lost
            // when the identity token is serialized using a security token handler.
            // To mitigate that, they are inferred from the claims or the security token.
            var properties = new AuthenticationProperties {
                ExpiresUtc = token.ValidTo,
                IssuedUtc  = token.ValidFrom
            };

            var audiences = principal.FindAll(JwtRegisteredClaimNames.Aud);

            if (audiences.Any())
            {
                properties.SetAudiences(audiences.Select(claim => claim.Value));
            }

            return(Task.FromResult(new AuthenticationTicket(principal, properties, Options.AuthenticationScheme)));
        }
        private async Task <AuthenticationTicket> DeserializeIdentityTokenAsync(string token, OpenIdConnectMessage request)
        {
            try {
                var notification = new DeserializeIdentityTokenContext(Context, Options, request, token)
                {
                    Issuer = Context.GetIssuer(Options),
                    SecurityTokenHandler = Options.IdentityTokenHandler,
                    SignatureProvider    = Options.SignatureProvider,
                    SigningKey           = Options.SigningCredentials.Select(credentials => credentials.Key).FirstOrDefault()
                };

                // Sets the default deserializer used to resolve the
                // authentication ticket corresponding to the identity token.
                notification.Deserializer = payload => {
                    if (notification.SecurityTokenHandler == null)
                    {
                        return(Task.FromResult <AuthenticationTicket>(null));
                    }

                    // Create new validation parameters to validate the security token.
                    // ValidateAudience and ValidateLifetime are always set to false:
                    // if necessary, the audience and the expiration can be validated
                    // in InvokeValidationEndpointAsync or InvokeTokenEndpointAsync.
                    var parameters = new TokenValidationParameters {
                        IssuerSigningKey = notification.SigningKey,
                        ValidIssuer      = notification.Issuer,
                        ValidateAudience = false,
                        ValidateLifetime = false
                    };

                    SecurityToken securityToken;
                    var           principal = notification.SecurityTokenHandler.ValidateToken(payload, parameters, out securityToken);

                    // Parameters stored in AuthenticationProperties are lost
                    // when the identity token is serialized using a security token handler.
                    // To mitigate that, they are inferred from the claims or the security token.
                    var properties = new AuthenticationProperties {
                        ExpiresUtc = securityToken.ValidTo,
                        IssuedUtc  = securityToken.ValidFrom
                    };

                    var audiences = principal.FindAll(JwtRegisteredClaimNames.Aud);
                    if (audiences.Any())
                    {
                        properties.SetAudiences(audiences.Select(claim => claim.Value));
                    }

                    var usage = principal.FindFirst(OpenIdConnectConstants.Extra.Usage);
                    if (usage != null)
                    {
                        properties.SetUsage(usage.Value);
                    }

                    if (principal.Claims.Any(claim => claim.Type == OpenIdConnectConstants.Extra.Confidential))
                    {
                        properties.Items[OpenIdConnectConstants.Extra.Confidential] = "true";
                    }

                    return(Task.FromResult(new AuthenticationTicket(principal, properties, Options.AuthenticationScheme)));
                };

                await Options.Provider.DeserializeIdentityToken(notification);

                // Directly return the authentication ticket if one
                // has been provided by DeserializeIdentityToken.
                // Treat a non-null ticket like an implicit HandleResponse call.
                if (notification.HandledResponse || notification.AuthenticationTicket != null)
                {
                    if (notification.AuthenticationTicket == null)
                    {
                        return(null);
                    }

                    // Ensure the received ticket is an identity token.
                    if (!notification.AuthenticationTicket.IsIdentityToken())
                    {
                        Logger.LogVerbose("The received token was not an identity token: {0}.", token);

                        return(null);
                    }

                    return(notification.AuthenticationTicket);
                }

                else if (notification.Skipped)
                {
                    return(null);
                }

                var ticket = await notification.DeserializeTicketAsync(token);

                if (ticket == null)
                {
                    return(null);
                }

                // Ensure the received ticket is an identity token.
                if (!ticket.IsIdentityToken())
                {
                    Logger.LogVerbose("The received token was not an identity token: {0}.", token);

                    return(null);
                }

                return(ticket);
            }

            catch (Exception exception) {
                Logger.LogWarning("An exception occured when deserializing an identity token.", exception);

                return(null);
            }
        }
        private async Task <AuthenticationTicket> DeserializeAccessTokenAsync(string token, OpenIdConnectMessage request)
        {
            var notification = new DeserializeAccessTokenContext(Context, Options, request, token)
            {
                DataFormat           = Options.AccessTokenFormat,
                Issuer               = Context.GetIssuer(Options),
                SecurityTokenHandler = Options.AccessTokenHandler,
                SignatureProvider    = Options.SignatureProvider,
                SigningCredentials   = Options.SigningCredentials.FirstOrDefault()
            };

            await Options.Provider.DeserializeAccessToken(notification);

            // Directly return the authentication ticket if one
            // has been provided by DeserializeAccessToken.
            if (notification.AuthenticationTicket != null)
            {
                return(notification.AuthenticationTicket);
            }

            var handler = notification.SecurityTokenHandler as ISecurityTokenValidator;

            if (handler == null)
            {
                return(notification.DataFormat?.Unprotect(token));
            }

            // Create new validation parameters to validate the security token.
            // ValidateAudience and ValidateLifetime are always set to false:
            // if necessary, the audience and the expiration can be validated
            // in InvokeValidationEndpointAsync or InvokeTokenEndpointAsync.
            var parameters = new TokenValidationParameters {
                IssuerSigningKey = notification.SigningCredentials.Key,
                ValidIssuer      = notification.Issuer,
                ValidateAudience = false,
                ValidateLifetime = false
            };

            SecurityToken   securityToken;
            ClaimsPrincipal principal;

            try {
                principal = handler.ValidateToken(token, parameters, out securityToken);
            }

            catch (Exception exception) {
                Logger.LogVerbose("An exception occured when deserializing an identity token: {Message}.", exception.Message);

                return(null);
            }

            // Parameters stored in AuthenticationProperties are lost
            // when the identity token is serialized using a security token handler.
            // To mitigate that, they are inferred from the claims or the security token.
            var properties = new AuthenticationProperties {
                ExpiresUtc = securityToken.ValidTo,
                IssuedUtc  = securityToken.ValidFrom
            };

            var audiences = principal.FindAll(JwtRegisteredClaimNames.Aud);

            if (audiences.Any())
            {
                properties.SetAudiences(audiences.Select(claim => claim.Value));
            }

            var usage = principal.FindFirst(OpenIdConnectConstants.Extra.Usage);

            if (usage != null)
            {
                properties.SetUsage(usage.Value);
            }

            if (principal.Claims.Any(claim => claim.Type == OpenIdConnectConstants.Extra.Confidential))
            {
                properties.Items[OpenIdConnectConstants.Extra.Confidential] = "true";
            }

            // Ensure the received ticket is an access token.
            var ticket = new AuthenticationTicket(principal, properties, Options.AuthenticationScheme);

            if (!ticket.IsAccessToken())
            {
                Logger.LogVerbose("The received token was not an access token: {Token}.", token);

                return(null);
            }

            return(ticket);
        }