Skip to content
This repository was archived by the owner on Dec 13, 2018. It is now read-only.

Commit 415055e

Browse files
committed
#1007 Additional id_token validation
1 parent 0c815da commit 415055e

File tree

1 file changed

+22
-10
lines changed

1 file changed

+22
-10
lines changed

src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectHandler.cs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ protected override async Task<AuthenticateResult> HandleRemoteAuthenticateAsync(
541541
Logger.ReceivedIdToken();
542542
ticket = ValidateToken(authorizationResponse.IdToken, properties, validationParameters, out jwt);
543543

544-
nonce = jwt?.Payload.Nonce;
544+
nonce = jwt.Payload.Nonce;
545545
if (!string.IsNullOrEmpty(nonce))
546546
{
547547
nonce = ReadNonceCookie(nonce);
@@ -599,22 +599,25 @@ protected override async Task<AuthenticateResult> HandleRemoteAuthenticateAsync(
599599
authorizationResponse = tokenResponseReceivedContext.ProtocolMessage;
600600
tokenEndpointResponse = tokenResponseReceivedContext.TokenEndpointResponse;
601601

602-
// We only have to process the IdToken if we didn't already get one in the AuthorizationResponse
603-
if (ticket == null)
604-
{
605-
// no need to validate signature when token is received using "code flow" as per spec
606-
// [http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation].
607-
validationParameters.RequireSignedTokens = false;
602+
// no need to validate signature when token is received using "code flow" as per spec
603+
// [http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation].
604+
validationParameters.RequireSignedTokens = false;
608605

609-
ticket = ValidateToken(tokenEndpointResponse.IdToken, properties, validationParameters, out jwt);
606+
// At least a cursory validation is required on the new IdToken, even if we've already validated the one from the authorization response.
607+
// And we'll want to validate the new JWT in ValidateTokenResponse.
608+
JwtSecurityToken tokenEndpointJwt;
609+
var tokenEndpointTicket = ValidateToken(tokenEndpointResponse.IdToken, properties, validationParameters, out tokenEndpointJwt);
610610

611-
nonce = jwt?.Payload.Nonce;
611+
// Avoid reading & deleting the nonce cookie, running the event, etc, if it was already done as part of the authorization response validation.
612+
if (ticket == null)
613+
{
614+
nonce = tokenEndpointJwt.Payload.Nonce;
612615
if (!string.IsNullOrEmpty(nonce))
613616
{
614617
nonce = ReadNonceCookie(nonce);
615618
}
616619

617-
var tokenValidatedContext = await RunTokenValidatedEventAsync(authorizationResponse, tokenEndpointResponse, properties, ticket, jwt, nonce);
620+
var tokenValidatedContext = await RunTokenValidatedEventAsync(authorizationResponse, tokenEndpointResponse, properties, tokenEndpointTicket, tokenEndpointJwt, nonce);
618621
if (tokenValidatedContext.CheckEventResult(out result))
619622
{
620623
return result;
@@ -626,6 +629,15 @@ protected override async Task<AuthenticateResult> HandleRemoteAuthenticateAsync(
626629
jwt = tokenValidatedContext.SecurityToken;
627630
nonce = tokenValidatedContext.Nonce;
628631
}
632+
else
633+
{
634+
if (!string.Equals(jwt.Subject, tokenEndpointJwt.Subject, StringComparison.Ordinal))
635+
{
636+
throw new SecurityTokenException("The sub claim does not match in the id_token's from the authorization and token endpoints.");
637+
}
638+
639+
jwt = tokenEndpointJwt;
640+
}
629641

630642
// Validate the token response if it wasn't provided manually
631643
if (!authorizationCodeReceivedContext.HandledCodeRedemption)

0 commit comments

Comments
 (0)