AzureAD / azure-activedirectory-identitymodel-extensions-for-dotnet

IdentityModel extensions for .Net
MIT License
1.06k stars 401 forks source link

Constructing JWTs with multiple audiences #39

Closed OnurGumus closed 10 years ago

OnurGumus commented 10 years ago

How would I construct a JWT with multiple audiences? There should be a constructor that takes a string[] for the audience.

brentschmaltz commented 10 years ago

You could add multiple 'aud' claims to the JwtSecurityToken constructor. Seems a bit awkward though.

herveyw-msft commented 10 years ago

Each audience should represent a "principal" that the token and its claims are directed to; having a token valid at two different principals might be considered "unusual", theoretically two consents would be required in an OAuth2 flow, for example. Beyond this, if tokens are encrypted and the audiences represent two different principals, then there would need to be two encryptions of the token (like JWE recipients).

brentschmaltz commented 10 years ago

It does seem 'unusual', the spec speaks of multiple 'aud' claims here: http://openid.net/specs/openid-connect-core-1_0.html#IDToken One of them must be the client_id, 'there may be others'. The reason for others is not defined.

This section http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation indicates if multiple 'aud' claims exist, then there SHOULD be an azp claim that matches the client_id.

@ReverseBlade, why are you thinking about having multiple 'aud' claims?

OnurGumus commented 10 years ago

I haven't read the spec. But JwtSecurityToken object has a property called Audiences which is collection of audiences. So I thought this is a supported scenario. I am Rolling a custom jtwtoken authentication in my Project. And there are multiple services that can consume the token from one hop to another. So I wanted to have multple auds so that I can have fine grained authentication mechanism by specifically stating some services can validate the token and some not. In this case you can group some services per audience. So I can say this token is valid for group A and B only.

brentschmaltz commented 10 years ago

Yes, the spec does support multiple audiences. So that is why the Audiences property returns IEnumerable, to support IDP's that send them. In this case there is the requirement of the 'azp' claim.

It is correct that an service should only accept a token that has an expected audience (in fact it should be the client_id). Are these services all web facing?

Still, there is no first class support for adding multiple audiences. You will have to add them by using Payload.AddClaim.

OnurGumus commented 10 years ago

Sorry for the late reply. Adding it to the payload won't work because after the token is constructed it becomes encoded. So adding to the payload won't alter the encoding. The only way to do is adding multiple claims

patrickmichalina commented 7 years ago

Interestingly enough, if you have multiple claims with the same key, it will automatically make a collection under that key. So this should work for you, even though the constructor doesn't support multiple:

public string Protect(AuthenticationTicket data)
{
   // set all your claims
   data.Identity.AddClaims(new[] { new Claim("aud", "Aud1"), new Claim("aud", "Aud2") });

   var token = new JwtSecurityToken("https://authserv.com", null, 
        data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime, signKey);

   var jwt = handler.WriteToken(token);

   return jwt;
}