Share via


SecurityTokenHandler.ValidateToken(SecurityToken) 메서드

정의

파생 클래스에서 재정의되는 경우 지정한 보안 토큰의 유효성을 검사합니다. 토큰은 파생된 클래스에서 처리되는 형식이어야 합니다.

public:
 virtual System::Collections::ObjectModel::ReadOnlyCollection<System::Security::Claims::ClaimsIdentity ^> ^ ValidateToken(System::IdentityModel::Tokens::SecurityToken ^ token);
public virtual System.Collections.ObjectModel.ReadOnlyCollection<System.Security.Claims.ClaimsIdentity> ValidateToken (System.IdentityModel.Tokens.SecurityToken token);
abstract member ValidateToken : System.IdentityModel.Tokens.SecurityToken -> System.Collections.ObjectModel.ReadOnlyCollection<System.Security.Claims.ClaimsIdentity>
override this.ValidateToken : System.IdentityModel.Tokens.SecurityToken -> System.Collections.ObjectModel.ReadOnlyCollection<System.Security.Claims.ClaimsIdentity>
Public Overridable Function ValidateToken (token As SecurityToken) As ReadOnlyCollection(Of ClaimsIdentity)

매개 변수

token
SecurityToken

유효성을 검사할 토큰입니다.

반환

토큰에 포함되어 있는 ID입니다.

예제

다음 코드에서는 재정의 ValidateToken 단순 웹 토큰 (SWT)를 처리 하는 보안 토큰 처리기에 대 한 메서드. 코드에서 수행 되는 CustomToken 샘플입니다. 이 샘플 및 WIF 및 다운로드할 위치에 사용할 수 있는 다른 샘플에 대 한 정보를 참조 하세요 WIF 코드 샘플 인덱스합니다.

/// <summary>
/// This method validates the Simple Web Token.
/// </summary>
/// <param name="token">A simple web token.</param>
/// <returns>A Claims Collection which contains all the claims from the token.</returns>
public override ReadOnlyCollection<ClaimsIdentity> ValidateToken(SecurityToken token)
{
    if ( token == null )
    {
        throw new ArgumentNullException( "token" );
    }

    SimpleWebToken simpleWebToken = token as SimpleWebToken;
    if ( simpleWebToken == null )
    {
        throw new ArgumentException("The token provided must be of type SimpleWebToken.");                    
    }

    if ( DateTime.Compare( simpleWebToken.ValidTo.Add( Configuration.MaxClockSkew ), DateTime.UtcNow ) <= 0 )
    {
        throw new SecurityTokenExpiredException("The incoming token has expired. Get a new access token from the Authorization Server.");
    }

    ValidateSignature( simpleWebToken );
 
    ValidateAudience( simpleWebToken.Audience );
 
    ClaimsIdentity claimsIdentity = CreateClaims( simpleWebToken );
   
    if (this.Configuration.SaveBootstrapContext)
    {
        claimsIdentity.BootstrapContext = new BootstrapContext(simpleWebToken.SerializedToken);
    }

    List<ClaimsIdentity> claimCollection = new List<ClaimsIdentity>(new ClaimsIdentity[] { claimsIdentity });
    return claimCollection.AsReadOnly();
}

다음 코드에서는 CreateClaims 재정의에서 호출 되는 메서드는 ValidateToken 이전 예제의 메서드. 이 메서드가 반환 된 ClaimsIdentity 토큰의 클레임에서 만들어지는 개체입니다. 코드에서 수행 되는 CustomToken 샘플입니다. 이 샘플 및 WIF 및 다운로드할 위치에 사용할 수 있는 다른 샘플에 대 한 정보를 참조 하세요 WIF 코드 샘플 인덱스합니다.

/// <summary>Creates <see cref="Claim"/>'s from the incoming token.
/// </summary>
/// <param name="simpleWebToken">The incoming <see cref="SimpleWebToken"/>.</param>
/// <returns>A <see cref="ClaimsIdentity"/> created from the token.</returns>
protected virtual ClaimsIdentity CreateClaims( SimpleWebToken simpleWebToken )
{
    if ( simpleWebToken == null )
    {
        throw new ArgumentNullException( "simpleWebToken" );
    }

    NameValueCollection tokenProperties = simpleWebToken.GetAllProperties();
    if ( tokenProperties == null )
    {
        throw new SecurityTokenValidationException( "No claims can be created from this Simple Web Token." );
    }

    if ( Configuration.IssuerNameRegistry == null )
    {
        throw new InvalidOperationException( "The Configuration.IssuerNameRegistry property of this SecurityTokenHandler is set to null. Tokens cannot be validated in this state." );
    }

    string normalizedIssuer = Configuration.IssuerNameRegistry.GetIssuerName( simpleWebToken );

    ClaimsIdentity identity = new ClaimsIdentity(AuthenticationTypes.Federation);
    
    foreach ( string key in tokenProperties.Keys )
    {
        if ( ! IsReservedKeyName(key) &&  !string.IsNullOrEmpty( tokenProperties[key] ) )
        {
            identity.AddClaim( new Claim( key, tokenProperties[key], ClaimValueTypes.String, normalizedIssuer ) );
            if ( key == AcsNameClaimType )
            {
                // add a default name claim from the Name identifier claim.
                identity.AddClaim( new Claim( DefaultNameClaimType, tokenProperties[key], ClaimValueTypes.String, normalizedIssuer ) );
            }
        }
    }

    return identity;
}

다음 코드에서는 ValidateSignature 재정의에서 호출 되는 메서드는 ValidateToken 단순 웹 토큰 처리기에서 메서드. 이 메서드는 토큰에 서명 구성를 사용 하 여 유효성을 검사 IssuerTokenResolver합니다. 코드에서 수행 되는 CustomToken 샘플입니다. 이 샘플 및 WIF 및 다운로드할 위치에 사용할 수 있는 다른 샘플에 대 한 정보를 참조 하세요 WIF 코드 샘플 인덱스합니다.

/// <summary>
/// Validates the signature on the incoming token.
/// </summary>
/// <param name="simpleWebToken">The incoming <see cref="SimpleWebToken"/>.</param>
protected virtual void ValidateSignature( SimpleWebToken simpleWebToken )
{
    if ( simpleWebToken == null )
    {
        throw new ArgumentNullException( "simpleWebToken" );
    }

    if ( String.IsNullOrEmpty( simpleWebToken.SerializedToken ) || String.IsNullOrEmpty( simpleWebToken.Signature ) )
    {
        throw new SecurityTokenValidationException( "The token does not have a signature to verify" );
    }

    string serializedToken = simpleWebToken.SerializedToken;           
    string unsignedToken = null;

    // Find the last parameter. The signature must be last per SWT specification.
    int lastSeparator = serializedToken.LastIndexOf( ParameterSeparator );

    // Check whether the last parameter is an hmac.
    if ( lastSeparator > 0 )
    {
        string lastParamStart = ParameterSeparator + SimpleWebTokenConstants.Signature + "=";
        string lastParam = serializedToken.Substring( lastSeparator );

        // Strip the trailing hmac to obtain the original unsigned string for later hmac verification.               
        if ( lastParam.StartsWith( lastParamStart, StringComparison.Ordinal ) )
        {
            unsignedToken = serializedToken.Substring( 0, lastSeparator );
        }
    }

    SimpleWebTokenKeyIdentifierClause clause = new SimpleWebTokenKeyIdentifierClause(simpleWebToken.Audience);
    InMemorySymmetricSecurityKey securityKey = null;
    try
    {
        securityKey = (InMemorySymmetricSecurityKey)this.Configuration.IssuerTokenResolver.ResolveSecurityKey(clause);
    }
    catch (InvalidOperationException)
    {
        throw new SecurityTokenValidationException( "A Symmetric key was not found for the given key identifier clause.");
    }

    string generatedSignature = GenerateSignature( unsignedToken, securityKey.GetSymmetricKey() );

    if ( string.CompareOrdinal( generatedSignature, simpleWebToken.Signature ) != 0 )
    {
        throw new SecurityTokenValidationException( "The signature on the incoming token is invalid.") ;
    }
}
/// <summary>
/// Generates an HMACSHA256 signature for a given string and key.
/// </summary>
/// <param name="unsignedToken">The token to be signed.</param>
/// <param name="signingKey">The key used to generate the signature.</param>
/// <returns>The generated signature.</returns>
protected static string GenerateSignature(string unsignedToken, byte[] signingKey)
{
    using (HMACSHA256 hmac = new HMACSHA256(signingKey))
    {
        byte[] signatureBytes = hmac.ComputeHash(Encoding.ASCII.GetBytes(unsignedToken));
        string signature = HttpUtility.UrlEncode(Convert.ToBase64String(signatureBytes));

        return signature;
    }
}

다음 코드에서는 ValidateAudience 재정의에서 호출 되는 메서드는 ValidateToken 단순 웹 토큰 처리기에서 메서드. 이 메서드는 대상 구성에 지정 된 Uri에 대 한 토큰에 포함 된 대상의 유효성을 검사 합니다. 코드에서 수행 되는 CustomToken 샘플입니다. 이 샘플 및 WIF 및 다운로드할 위치에 사용할 수 있는 다른 샘플에 대 한 정보를 참조 하세요 WIF 코드 샘플 인덱스합니다.

/// <summary>
/// Validates the audience of the incoming token with those specified in configuration.
/// </summary>
/// <param name="tokenAudience">The audience of the incoming token.</param>
protected virtual void ValidateAudience( string tokenAudience )
{
    if ( Configuration.AudienceRestriction.AudienceMode != AudienceUriMode.Never )
    {
        if ( String.IsNullOrEmpty( tokenAudience ) )
        {
            throw new SecurityTokenValidationException("The incoming token does not have a valid audience Uri and the Audience Restriction is not set to 'None'.");
        }

        if ( Configuration.AudienceRestriction.AllowedAudienceUris.Count == 0 )
        {
            throw new InvalidOperationException( " Audience Restriction is not set to 'None' but no valid audience URI's are configured." );
        }

        IList<Uri> allowedAudienceUris = Configuration.AudienceRestriction.AllowedAudienceUris;
        
        Uri audienceUri = null;

        Uri.TryCreate(tokenAudience, UriKind.RelativeOrAbsolute, out audienceUri);
        
        // Strip off any query string or fragment. 
        Uri audienceLeftPart;

        if ( audienceUri.IsAbsoluteUri )
        {
            audienceLeftPart = new Uri( audienceUri.GetLeftPart( UriPartial.Path ) );
        }
        else
        {
            Uri baseUri = new Uri( "http://www.example.com" );
            Uri resolved = new Uri( baseUri, tokenAudience );
            audienceLeftPart = baseUri.MakeRelativeUri( new Uri( resolved.GetLeftPart( UriPartial.Path ) ) );
        }

        if ( !allowedAudienceUris.Contains( audienceLeftPart ) )
        {
            throw new AudienceUriValidationFailedException(
                    "The Audience Uri of the incoming token is not present in the list of permitted Audience Uri's.");
        }
    }
}

설명

기본적으로이 메서드에서 throw 한 NotImplementedException 예외입니다.

ValidateToken 의 유효성을 검사 하 고 역직렬화된 보안 토큰에서 클레임을 추출 하는 인프라에서 호출 됩니다. 이러한 클레임의 컬렉션에 반환 됩니다 ClaimsIdentity 메서드에 의해 반환 되는 개체입니다. 일반적인 경우이 컬렉션에는 단일 id를 포함 됩니다.

파생된 클래스에서 유효성 검사 일반적으로 포함 Uri에 지정 된 대상에 대 한 토큰에 지정 된 대상의 유효성을 검사 합니다 SecurityTokenHandlerConfiguration.AudienceRestriction 에 지정 된 토큰 처리기 구성 개체의 속성을 Configuration 속성입니다. 이러한 URI는 일반적으로 audienceUris 요소 아래의 <구성 파일에 설정됩니다> . 대상 그룹을 확인할 수 없는 경우는 AudienceUriValidationFailedException 예외를 throw 해야 합니다.

토큰을 처리할 때 발급자는 일반적으로 유효성을 검사 중 하나에 발급자 토큰을 전달 하 여는 GetIssuerName 메서드를 IssuerNameRegistry 를 통해 처리기에 대해 구성 된 개체를 Configuration 속성입니다. 발급자 이름 레지스트리는 일반적으로 구성 파일의 <issuerNameRegistry> 요소를 통해 구성됩니다. GetIssuerName 발급자의 이름을 반환 합니다. 이 이름은 설정에 사용할는 Claim.Issuer 토큰에 포함 된 클레임의 속성입니다. 발급자 이름 레지스트리 발급자 토큰에 대 한 항목이 없으면 GetIssuerName 반환 null합니다. 이 경우에 SecurityTokenException 는 일반적으로 파생된 클래스에서 throw 하지만이 동작은 디자이너 클래스의 최대입니다.

적용 대상