Restore JwtFormat IIssuerSecurityTokenProvider lazy usage so refreshing providers work.

This commit is contained in:
Chris Ross 2014-05-27 14:43:18 -07:00
Родитель a2b95f0876
Коммит 45a9f7b328
4 изменённых файлов: 76 добавлений и 43 удалений

Просмотреть файл

@ -33,25 +33,24 @@ namespace Owin
JwtFormat jwtFormat = null;
if (options.TokenValidationParameters != null)
{
// Don't override explicit user settings.
if (options.TokenValidationParameters.IssuerSigningTokens == null
|| !options.TokenValidationParameters.IssuerSigningTokens.Any())
{
options.TokenValidationParameters.IssuerSigningTokens = cachingSecurityTokenProvider.SecurityTokens;
}
if (string.IsNullOrWhiteSpace(options.TokenValidationParameters.ValidIssuer)
&& (options.TokenValidationParameters.ValidIssuers == null
|| !options.TokenValidationParameters.ValidIssuers.Any())
&& options.TokenValidationParameters.IssuerValidator == null)
{
options.TokenValidationParameters.ValidIssuer = cachingSecurityTokenProvider.Issuer;
}
// Carry over obsolete property if set
if (!string.IsNullOrWhiteSpace(options.Audience))
{
// Carry over obsolete property if set
if (string.IsNullOrWhiteSpace(options.TokenValidationParameters.ValidAudience))
{
options.TokenValidationParameters.ValidAudience = options.Audience;
}
jwtFormat = new JwtFormat(options.TokenValidationParameters);
else if (options.TokenValidationParameters.ValidAudiences == null)
{
options.TokenValidationParameters.ValidAudiences = new[] { options.Audience };
}
else
{
options.TokenValidationParameters.ValidAudiences = options.TokenValidationParameters.ValidAudiences.Concat(new[] { options.Audience });
}
}
jwtFormat = new JwtFormat(options.TokenValidationParameters, cachingSecurityTokenProvider);
}
else
{

Просмотреть файл

@ -45,25 +45,24 @@ namespace Owin
JwtFormat jwtFormat = null;
if (options.TokenValidationParameters != null)
{
// Don't override explicit user settings.
if (options.TokenValidationParameters.IssuerSigningTokens == null
|| !options.TokenValidationParameters.IssuerSigningTokens.Any())
{
options.TokenValidationParameters.IssuerSigningTokens = cachingSecurityTokenProvider.SecurityTokens;
}
if (string.IsNullOrWhiteSpace(options.TokenValidationParameters.ValidIssuer)
&& (options.TokenValidationParameters.ValidIssuers == null
|| !options.TokenValidationParameters.ValidIssuers.Any())
&& options.TokenValidationParameters.IssuerValidator == null)
{
options.TokenValidationParameters.ValidIssuer = cachingSecurityTokenProvider.Issuer;
}
// Carry over obsolete property if set
if (!string.IsNullOrWhiteSpace(options.Audience))
{
// Carry over obsolete property if set
if (string.IsNullOrWhiteSpace(options.TokenValidationParameters.ValidAudience))
{
options.TokenValidationParameters.ValidAudience = options.Audience;
}
jwtFormat = new JwtFormat(options.TokenValidationParameters);
else if (options.TokenValidationParameters.ValidAudiences == null)
{
options.TokenValidationParameters.ValidAudiences = new[] { options.Audience };
}
else
{
options.TokenValidationParameters.ValidAudiences = options.TokenValidationParameters.ValidAudiences.Concat(new[] { options.Audience });
}
}
jwtFormat = new JwtFormat(options.TokenValidationParameters, cachingSecurityTokenProvider);
}
else
{

Просмотреть файл

@ -15,7 +15,8 @@ namespace Microsoft.Owin.Security.Jwt
/// </summary>
public class JwtFormat : ISecureDataFormat<AuthenticationTicket>
{
private TokenValidationParameters _validationParameters;
private readonly TokenValidationParameters _validationParameters;
private readonly IEnumerable<IIssuerSecurityTokenProvider> _issuerCredentialProviders;
/// <summary>
/// Initializes a new instance of the <see cref="JwtFormat"/> class.
@ -39,10 +40,8 @@ namespace Microsoft.Owin.Security.Jwt
_validationParameters = new TokenValidationParameters()
{
ValidAudience = allowedAudience,
ValidIssuer = issuerCredentialProvider.Issuer,
IssuerSigningTokens = issuerCredentialProvider.SecurityTokens.ToList(),
ValidateIssuer = true
};
_issuerCredentialProviders = new[] { issuerCredentialProvider };
}
/// <summary>
@ -78,12 +77,8 @@ namespace Microsoft.Owin.Security.Jwt
_validationParameters = new TokenValidationParameters()
{
ValidAudiences = audiences,
ValidIssuers = credentialProviders.Select(provider => provider.Issuer).ToList(),
IssuerSigningTokens = credentialProviders
.Select(provider => provider.SecurityTokens.ToList())
.Aggregate((l1, l2) => { l1.AddRange(l2); return l1; }),
ValidateIssuer = true
};
_issuerCredentialProviders = issuerCredentialProviders;
}
/// <summary>
@ -103,6 +98,17 @@ namespace Microsoft.Owin.Security.Jwt
_validationParameters = validationParameters;
}
public JwtFormat(TokenValidationParameters validationParameters, IIssuerSecurityTokenProvider issuerCredentialProvider)
: this(validationParameters)
{
if (issuerCredentialProvider == null)
{
throw new ArgumentNullException("issuerCredentialProvider");
}
_issuerCredentialProviders = new[] { issuerCredentialProvider };
}
/// <summary>
/// Gets or sets a value indicating whether JWT issuers should be validated.
/// </summary>
@ -162,7 +168,35 @@ namespace Microsoft.Owin.Security.Jwt
throw new ArgumentOutOfRangeException("protectedText", Properties.Resources.Exception_InvalidJwt);
}
ClaimsPrincipal claimsPrincipal = TokenHandler.ValidateToken(protectedText, _validationParameters);
TokenValidationParameters validationParameters = _validationParameters;
if (_issuerCredentialProviders != null)
{
// Lazy augment with issuers and tokens. Note these may be refreshed periodically.
validationParameters = new TokenValidationParameters(validationParameters);
IEnumerable<string> issuers = _issuerCredentialProviders.Select(provider => provider.Issuer);
if (validationParameters.ValidIssuers == null)
{
validationParameters.ValidIssuers = issuers;
}
else
{
validationParameters.ValidIssuers = validationParameters.ValidAudiences.Concat(issuers);
}
IEnumerable<SecurityToken> tokens = _issuerCredentialProviders.Select(provider => provider.SecurityTokens)
.Aggregate((left, right) => left.Concat(right));
if (validationParameters.IssuerSigningTokens == null)
{
validationParameters.IssuerSigningTokens = tokens;
}
else
{
validationParameters.IssuerSigningTokens = validationParameters.IssuerSigningTokens.Concat(tokens);
}
}
ClaimsPrincipal claimsPrincipal = TokenHandler.ValidateToken(protectedText, validationParameters);
var claimsIdentity = (ClaimsIdentity)claimsPrincipal.Identity;
// Fill out the authenticationProperties issued and expires times if the equivalent claims are in the JWT

Просмотреть файл

@ -17,7 +17,8 @@ namespace Microsoft.Owin.Security.Tests
[Fact]
public void HandlerConstructorShouldThrowWhenAnAllowedAudienceIsNotSpecified()
{
Should.Throw<ArgumentNullException>(() => new JwtFormat(null, (IIssuerSecurityTokenProvider)null));
Should.Throw<ArgumentNullException>(() => new JwtFormat((string)null, (IIssuerSecurityTokenProvider)null));
Should.Throw<ArgumentNullException>(() => new JwtFormat((TokenValidationParameters)null, (IIssuerSecurityTokenProvider)null));
}
[Fact]