Reputation: 88
Scenario: I have 2 AAD applications in different Azure tenants - lets call Tenant A and B. The app in tenant A defines custom appRole and oAuth2Permissions that have been consented to by app in Tenant B. The app in Tenant B defines a KeyCredential using its own cert.
I am able to get a JWT token successfully using ADAL v3 passing in the
ClientAssertionCertificate (resource is the app in Tenant A and client is the app in Tenant B) like so:
AuthenticationContext authenticationContext = new AuthenticationContext(authority, false);
X509Certificate2 cert = AuthHelper.FindCertificateByThumbprint("<Thumbprint of the Tenant B app's KeyCredential cert>");
ClientAssertionCertificate assertionCert = new ClientAssertionCertificate(clientId, cert);
AuthenticationResult authenticationResult = authenticationContext.AcquireTokenAsync(resource, assertionCert).Result;
string accessToken = authenticationResult.AccessToken; // Valid.
string idToken = authenticationResult.IdToken; // Null.
The AuthenticationResult from AcquireTokenAsync contains the AccessToken that I can validate successfully as well...
string issuer = string.Format(ConfigurationManager.AppSettings["issuer"], ConfigurationManager.AppSettings["tenantid"]);
string audience = ConfigurationManager.AppSettings["audience"];
string certThumbprint = ConfigurationManager.AppSettings["certThumbprint"];
var stsDiscoveryEndpoint = string.Concat(issuer, URI_DELIMITER, STS_DISCOVERY_ENDPOINT_SUFFIX);
ConfigurationManager<OpenIdConnectConfiguration> configManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint);
var config = configManager.GetConfigurationAsync().Result;
// extract issuer and token for validation
var authority = config.Issuer;
var signingTokens = config.SigningTokens.ToList();
sys.TokenValidationParameters validationParameters = new sys.TokenValidationParameters
{
ValidIssuer = issuer,
ValidAudience = audience,
ValidateLifetime = true,
IssuerSigningTokens = signingTokens,
CertificateValidator = X509CertificateValidator.None,
};
sys.JwtSecurityTokenHandler tokendHandler = new sys.JwtSecurityTokenHandler();
sys.SecurityToken jwt;
var result = tokendHandler.ValidateToken(token, validationParameters, out jwt);
The IdToken is however empty. Is this because I have no UserAssertion passed in to the AcquireTokenAsync call?
To be able to further Authorize the request, I'm looking for - appRole, oAuth2Permissions and groupMembership claims. These claims are however not in the AccessToken. If this is expected, then when do I find the said claims in the token. If this is not expected, what am I missing in the token generation or AAD app setup that would cause this?
NOTE: My scenario does not involve Web APIs (but it is WAAD bound) so I'd have to do the token validation and authorization manually.
Upvotes: 2
Views: 383
Reputation: 12434
ID token is only generated if you follow authentication flows involving a user. At no point in your authentication do you sign the user in, so I cannot understand what kind of ID Token you would expect to get...
You need to follow the Authorization Code Grant flow to sign in a user, and get a delegated token.
I have a blog post on how to get groupMembership claims to appear between two applications.
There is no such think as an "oAuth2Permission" claim in an access token. You can find all the different tokens and claims supported by AAD here.
Ultimately, you should be relying on the AAD Graph API to get these details, not the token, because the token has intrinsic size limits which may leave out data about certain roles or groups which exist.
Upvotes: 1