Sdílet prostřednictvím


SecurityTokenHandler.ValidateToken(SecurityToken) Metoda

Definice

Při přepsání v odvozené třídě ověří zadaný token zabezpečení. Token musí být typu zpracovaného odvozenou třídou.

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)

Parametry

token
SecurityToken

Token, který se má ověřit.

Návraty

Identity obsažené v tokenu.

Příklady

Následující kód ukazuje přepsání ValidateToken metody pro obslužnou rutinu tokenů zabezpečení, která zpracovává jednoduché webové tokeny (SWT). Kód je převzat z ukázky CustomToken . Informace o této ukázce a dalších ukázkách dostupných pro WIF a o tom, kde si je stáhnout, najdete v tématu Index ukázek kódu 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();
}

Následující kód ukazuje CreateClaims metodu, která je vyvolána z přepsání ValidateToken metody v předchozím příkladu. Tato metoda vrátí ClaimsIdentity objekt, který je vytvořen z deklarací identity v tokenu. Kód je převzat z ukázky CustomToken . Informace o této ukázce a dalších ukázkách dostupných pro WIF a o tom, kde si je stáhnout, najdete v tématu Index ukázek kódu 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;
}

Následující kód ukazuje ValidateSignature metodu, která je vyvolána z přepsání ValidateToken metody v jednoduché obslužné rutině webového tokenu. Tato metoda ověří podpis na tokenu pomocí nakonfigurovaného IssuerTokenResolver. Kód je převzat z ukázky CustomToken . Informace o této ukázce a dalších ukázkách dostupných pro WIF a o tom, kde si je stáhnout, najdete v tématu Index ukázek kódu 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;
    }
}

Následující kód ukazuje ValidateAudience metodu, která je vyvolána z přepsání ValidateToken metody v jednoduché obslužné rutině webového tokenu. Tato metoda ověří cílovou skupinu obsaženou v tokenu proti identifikátorům URI cílové skupiny, které byly zadány v konfiguraci. Kód je převzat z ukázky CustomToken . Informace o této ukázce a dalších ukázkách dostupných pro WIF a o tom, kde si je stáhnout, najdete v tématu Index ukázek kódu 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.");
        }
    }
}

Poznámky

Ve výchozím nastavení tato metoda vyvolá NotImplementedException výjimku.

Metoda ValidateToken je volána infrastrukturou k ověření a extrakci deklarací identity z deserializovaného tokenu zabezpečení. Tyto deklarace identity jsou vráceny v kolekci ClaimsIdentity objektů vrácených metodou. V typickém případě bude tato kolekce obsahovat jednu identitu.

V odvozených třídách ověřování obvykle zahrnuje ověření zamýšlené cílové skupiny zadané v tokenu s identifikátory URI cílové skupiny zadané ve SecurityTokenHandlerConfiguration.AudienceRestriction vlastnosti objektu konfigurace obslužné rutiny tokenu zadaného Configuration ve vlastnosti. Tyto identifikátory URI se obvykle nastavují v konfiguračním souboru pod elementem <audienceUris> . Pokud cílovou skupinu nelze ověřit, AudienceUriValidationFailedException měla by se vyvolat výjimka.

Při zpracování tokenu se vystavitel obvykle ověřuje předáním tokenu vystavitele jedné z GetIssuerName metod na objektu IssuerNameRegistry , který je nakonfigurován pro obslužnou rutinu Configuration prostřednictvím vlastnosti. Registr názvu vystavitele se obvykle konfiguruje prostřednictvím elementu <issuerNameRegistry> v konfiguračním souboru. Vrátí GetIssuerName název vystavitele. Tento název by se měl použít k nastavení Claim.Issuer vlastnosti v deklarací identity obsažené v tokenu. Pokud registr názvu vystavitele neobsahuje položku pro token vystavitele, GetIssuerName vrátí nullhodnotu . V tomto případě SecurityTokenException je obvykle vyvolán v odvozených třídách, ale toto chování je na návrháři třídy.

Platí pro