SecurityTokenHandler.ValidateToken(SecurityToken) Metoda
Definice
Důležité
Některé informace platí pro předběžně vydaný produkt, který se může zásadně změnit, než ho výrobce nebo autor vydá. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
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í null
hodnotu . 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.