Skip to content

Commit 4413088

Browse files
authored
general code cleanup focus on AadIssuerValidator (#79)
Support JwtSecurityToken and JsonWebToken Get 'tid' right from payload, no need to create claims Use ConcurrentDictionary Create ConfigurationManager once on startup. Set the dictionary rather than Add as duplicates will fault. Add try / catch to stop faulting System usings first
1 parent 71b9c32 commit 4413088

10 files changed

+442
-367
lines changed

Microsoft.Identity.Web/Constants.cs renamed to Microsoft.Identity.Web/ClaimConstants.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,15 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2525
namespace Microsoft.Identity.Web
2626
{
2727
/// <summary>
28-
/// claim keys constants
28+
/// Constants for claim types.
2929
/// </summary>
3030
public static class ClaimConstants
3131
{
32+
public const string Name = "name";
3233
public const string ObjectId = "http://schemas.microsoft.com/identity/claims/objectidentifier";
34+
public const string Oid = "oid";
35+
public const string PreferredUserName = "preferred_username";
3336
public const string TenantId = "http://schemas.microsoft.com/identity/claims/tenantid";
34-
public const string tid = "tid";
37+
public const string Tid = "tid";
3538
}
36-
}
39+
}
Lines changed: 61 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,43 @@
1-
using Microsoft.Identity.Client;
1+
/************************************************************************************************
2+
The MIT License (MIT)
3+
4+
Copyright (c) 2015 Microsoft Corporation
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
***********************************************************************************************/
24+
25+
using Microsoft.Identity.Client;
226
using System.Security.Claims;
327

428
namespace Microsoft.Identity.Web
529
{
630
public static class ClaimsPrincipalExtension
731
{
832
/// <summary>
9-
/// Get the Account identifier for an MSAL.NET account from a ClaimsPrincipal
33+
/// Gets the Account identifier for an MSAL.NET account from a <see cref="ClaimsPrincipal"/>
1034
/// </summary>
1135
/// <param name="claimsPrincipal">Claims principal</param>
1236
/// <returns>A string corresponding to an account identifier as defined in <see cref="Microsoft.Identity.Client.AccountId.Identifier"/></returns>
1337
public static string GetMsalAccountId(this ClaimsPrincipal claimsPrincipal)
1438
{
1539
string userObjectId = GetObjectId(claimsPrincipal);
1640
string tenantId = GetTenantId(claimsPrincipal);
17-
1841
if (!string.IsNullOrWhiteSpace(userObjectId) && !string.IsNullOrWhiteSpace(tenantId))
1942
{
2043
return $"{userObjectId}.{tenantId}";
@@ -24,41 +47,37 @@ public static string GetMsalAccountId(this ClaimsPrincipal claimsPrincipal)
2447
}
2548

2649
/// <summary>
27-
/// Get the unique object ID associated with the claimsPrincipal
50+
/// Gets the unique object ID associated with the <see cref="ClaimsPrincipal"/>
2851
/// </summary>
29-
/// <param name="claimsPrincipal">Claims principal from which to retrieve the unique object id</param>
52+
/// <param name="claimsPrincipal">the <see cref="ClaimsPrincipal"/> from which to retrieve the unique object id</param>
3053
/// <returns>Unique object ID of the identity, or <c>null</c> if it cannot be found</returns>
3154
public static string GetObjectId(this ClaimsPrincipal claimsPrincipal)
32-
{
33-
string userObjectId = claimsPrincipal.FindFirstValue(ClaimConstants.ObjectId);
55+
{
56+
string userObjectId = claimsPrincipal.FindFirstValue(ClaimConstants.Oid);
3457
if (string.IsNullOrEmpty(userObjectId))
35-
{
36-
userObjectId = claimsPrincipal.FindFirstValue("oid");
37-
}
58+
userObjectId = claimsPrincipal.FindFirstValue(ClaimConstants.ObjectId);
3859

3960
return userObjectId;
4061
}
4162

4263
/// <summary>
43-
/// Tenant ID of the identity
64+
/// Gets the Tenant ID associated with the <see cref="ClaimsPrincipal"/>
4465
/// </summary>
45-
/// <param name="claimsPrincipal">Claims principal from which to retrieve the tenant id</param>
66+
/// <param name="claimsPrincipal">the <see cref="ClaimsPrincipal"/> from which to retrieve the tenant id</param>
4667
/// <returns>Tenant ID of the identity, or <c>null</c> if it cannot be found</returns>
4768
public static string GetTenantId(this ClaimsPrincipal claimsPrincipal)
4869
{
49-
string tenantId = claimsPrincipal.FindFirstValue(ClaimConstants.TenantId);
70+
string tenantId = claimsPrincipal.FindFirstValue(ClaimConstants.Tid);
5071
if (string.IsNullOrEmpty(tenantId))
51-
{
52-
tenantId = claimsPrincipal.FindFirstValue("tid");
53-
}
72+
tenantId = claimsPrincipal.FindFirstValue(ClaimConstants.TenantId);
5473

5574
return tenantId;
5675
}
5776

5877
/// <summary>
59-
/// Gets the login-hint associated with an identity
78+
/// Gets the login-hint associated with a <see cref="ClaimsPrincipal"/>
6079
/// </summary>
61-
/// <param name="claimsPrincipal">Identity for which to compte the login-hint</param>
80+
/// <param name="claimsPrincipal">Identity for which to complete the login-hint</param>
6281
/// <returns>login-hint for the identity, or <c>null</c> if it cannot be found</returns>
6382
public static string GetLoginHint(this ClaimsPrincipal claimsPrincipal)
6483
{
@@ -76,13 +95,11 @@ public static string GetDomainHint(this ClaimsPrincipal claimsPrincipal)
7695
const string msaTenantId = "9188040d-6c67-4c5b-b112-36a304b66dad";
7796

7897
var tenantId = GetTenantId(claimsPrincipal);
79-
string domainHint = string.IsNullOrWhiteSpace(tenantId) ? null :
80-
tenantId == msaTenantId ? "consumers" : "organizations";
81-
return domainHint;
98+
return string.IsNullOrWhiteSpace(tenantId) ? null : tenantId == msaTenantId ? "consumers" : "organizations";
8299
}
83100

84101
/// <summary>
85-
/// Get the display name for the signed-in user, based on their claims principal
102+
/// Get the display name for the signed-in user, from the <see cref="ClaimsPrincipal"/>
86103
/// </summary>
87104
/// <param name="claimsPrincipal">Claims about the user/account</param>
88105
/// <returns>A string containing the display name for the user, as brought by Azure AD v1.0 and v2.0 tokens,
@@ -91,7 +108,7 @@ public static string GetDomainHint(this ClaimsPrincipal claimsPrincipal)
91108
public static string GetDisplayName(this ClaimsPrincipal claimsPrincipal)
92109
{
93110
// Attempting the claims brought by an Azure AD v2.0 token first
94-
string displayName = claimsPrincipal.FindFirstValue("preferred_username");
111+
string displayName = claimsPrincipal.FindFirstValue(ClaimConstants.PreferredUserName);
95112

96113
// Otherwise falling back to the claims brought by an Azure AD v1.0 token
97114
if (string.IsNullOrWhiteSpace(displayName))
@@ -102,8 +119,9 @@ public static string GetDisplayName(this ClaimsPrincipal claimsPrincipal)
102119
// Finally falling back to name
103120
if (string.IsNullOrWhiteSpace(displayName))
104121
{
105-
displayName = claimsPrincipal.FindFirstValue("name");
122+
displayName = claimsPrincipal.FindFirstValue(ClaimConstants.Name);
106123
}
124+
107125
return displayName;
108126
}
109127

@@ -131,32 +149,35 @@ public static string GetDisplayName(this ClaimsPrincipal claimsPrincipal)
131149
/// </example>
132150
public static ClaimsPrincipal FromTenantIdAndObjectId(string tenantId, string objectId)
133151
{
134-
var tidClaim = new Claim("tid", tenantId);
135-
var oidClaim = new Claim("oid", objectId);
136-
var claimsIdentity = new ClaimsIdentity();
137-
claimsIdentity.AddClaims(new Claim[] { oidClaim, tidClaim });
138-
var principal = new ClaimsPrincipal();
139-
principal.AddIdentity(claimsIdentity);
140-
return principal;
152+
return new ClaimsPrincipal(
153+
new ClaimsIdentity(new Claim[]
154+
{
155+
new Claim(ClaimConstants.Tid, tenantId),
156+
new Claim(ClaimConstants.Oid, objectId)
157+
})
158+
);
141159
}
142160

143161
/// <summary>
144-
/// Builds a ClaimsPrincipal from an IAccount
162+
/// Creates the <see cref="ClaimsPrincipal"/> from the values found in an <see cref="IAccount"/>
145163
/// </summary>
146-
/// <param name="account">The IAccount instance.</param>
147-
/// <returns>A ClaimsPrincipal built from IAccount</returns>
164+
/// <param name="account">The IAccount instance</param>
165+
/// <returns>A <see cref="ClaimsPrincipal"/> built from IAccount</returns>
148166
public static ClaimsPrincipal ToClaimsPrincipal(this IAccount account)
149167
{
150168
if (account != null)
151169
{
152-
var identity = new ClaimsIdentity();
153-
identity.AddClaim(new Claim(ClaimConstants.ObjectId, account.HomeAccountId.ObjectId));
154-
identity.AddClaim(new Claim(ClaimConstants.TenantId, account.HomeAccountId.TenantId));
155-
identity.AddClaim(new Claim(ClaimTypes.Upn, account.Username));
156-
return new ClaimsPrincipal(identity);
170+
return new ClaimsPrincipal(
171+
new ClaimsIdentity(new Claim[]
172+
{
173+
new Claim(ClaimConstants.Oid, account.HomeAccountId.ObjectId),
174+
new Claim(ClaimConstants.Tid, account.HomeAccountId.TenantId),
175+
new Claim(ClaimTypes.Upn, account.Username)
176+
})
177+
);
157178
}
158179

159180
return null;
160181
}
161182
}
162-
}
183+
}

Microsoft.Identity.Web/Client/TokenAcquisition.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ public class TokenAcquisition : ITokenAcquisition
6464
/// <param name="configuration"></param>
6565
public TokenAcquisition(IConfiguration configuration, IMSALAppTokenCacheProvider appTokenCacheProvider, IMSALUserTokenCacheProvider userTokenCacheProvider)
6666
{
67+
if (configuration == null)
68+
throw new ArgumentNullException(nameof(configuration));
69+
6770
azureAdOptions = new AzureADOptions();
6871
configuration.Bind("AzureAD", azureAdOptions);
6972

@@ -136,6 +139,7 @@ public async Task AddAccountToCacheFromAuthorizationCode(AuthorizationCodeReceiv
136139
}
137140
catch (MsalException ex)
138141
{
142+
// brentsch - todo, write to a log
139143
Debug.WriteLine(ex.Message);
140144
throw;
141145
}

Microsoft.Identity.Web/Client/TokenCacheProviders/Session/MSALAppSessionTokenCacheProviderExtension.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,7 @@ public static IServiceCollection AddSessionAppTokenCache(this IServiceCollection
4848
{
4949
services.AddScoped<IMSALAppTokenCacheProvider>(factory =>
5050
{
51-
var optionsMonitor = factory.GetRequiredService<IOptionsMonitor<AzureADOptions>>();
52-
53-
return new MSALAppSessionTokenCacheProvider(optionsMonitor);
51+
return new MSALAppSessionTokenCacheProvider(factory.GetRequiredService<IOptionsMonitor<AzureADOptions>>());
5452
});
5553

5654
return services;

0 commit comments

Comments
 (0)