diff --git a/src/Identity/Extensions.Core/ref/Microsoft.Extensions.Identity.Core.netcoreapp.cs b/src/Identity/Extensions.Core/ref/Microsoft.Extensions.Identity.Core.netcoreapp.cs index 13979d60ae..fa44115139 100644 --- a/src/Identity/Extensions.Core/ref/Microsoft.Extensions.Identity.Core.netcoreapp.cs +++ b/src/Identity/Extensions.Core/ref/Microsoft.Extensions.Identity.Core.netcoreapp.cs @@ -15,6 +15,7 @@ namespace Microsoft.AspNetCore.Identity public partial class ClaimsIdentityOptions { public ClaimsIdentityOptions() { } + public string EmailClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string RoleClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string SecurityStampClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string UserIdClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } diff --git a/src/Identity/Extensions.Core/ref/Microsoft.Extensions.Identity.Core.netstandard2.0.cs b/src/Identity/Extensions.Core/ref/Microsoft.Extensions.Identity.Core.netstandard2.0.cs index 13979d60ae..fa44115139 100644 --- a/src/Identity/Extensions.Core/ref/Microsoft.Extensions.Identity.Core.netstandard2.0.cs +++ b/src/Identity/Extensions.Core/ref/Microsoft.Extensions.Identity.Core.netstandard2.0.cs @@ -15,6 +15,7 @@ namespace Microsoft.AspNetCore.Identity public partial class ClaimsIdentityOptions { public ClaimsIdentityOptions() { } + public string EmailClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string RoleClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string SecurityStampClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string UserIdClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } diff --git a/src/Identity/Extensions.Core/src/ClaimsIdentityOptions.cs b/src/Identity/Extensions.Core/src/ClaimsIdentityOptions.cs index 54ba1ae069..17f383ab33 100644 --- a/src/Identity/Extensions.Core/src/ClaimsIdentityOptions.cs +++ b/src/Identity/Extensions.Core/src/ClaimsIdentityOptions.cs @@ -25,9 +25,14 @@ namespace Microsoft.AspNetCore.Identity /// public string UserIdClaimType { get; set; } = ClaimTypes.NameIdentifier; + /// + /// Gets or sets the ClaimType used for the user email claim. Defaults to . + /// + public string EmailClaimType { get; set; } = ClaimTypes.Email; + /// /// Gets or sets the ClaimType used for the security stamp claim. Defaults to "AspNet.Identity.SecurityStamp". /// public string SecurityStampClaimType { get; set; } = "AspNet.Identity.SecurityStamp"; } -} \ No newline at end of file +} diff --git a/src/Identity/Extensions.Core/src/UserClaimsPrincipalFactory.cs b/src/Identity/Extensions.Core/src/UserClaimsPrincipalFactory.cs index dd7e316423..859e78ad57 100644 --- a/src/Identity/Extensions.Core/src/UserClaimsPrincipalFactory.cs +++ b/src/Identity/Extensions.Core/src/UserClaimsPrincipalFactory.cs @@ -81,6 +81,14 @@ namespace Microsoft.AspNetCore.Identity Options.ClaimsIdentity.RoleClaimType); id.AddClaim(new Claim(Options.ClaimsIdentity.UserIdClaimType, userId)); id.AddClaim(new Claim(Options.ClaimsIdentity.UserNameClaimType, userName)); + if (UserManager.SupportsUserEmail) + { + var email = await UserManager.GetEmailAsync(user); + if (!string.IsNullOrEmpty(email)) + { + id.AddClaim(new Claim(Options.ClaimsIdentity.EmailClaimType, email)); + } + } if (UserManager.SupportsUserSecurityStamp) { id.AddClaim(new Claim(Options.ClaimsIdentity.SecurityStampClaimType, @@ -154,4 +162,4 @@ namespace Microsoft.AspNetCore.Identity return id; } } -} \ No newline at end of file +} diff --git a/src/Identity/test/Identity.Test/UserClaimsPrincipalFactoryTest.cs b/src/Identity/test/Identity.Test/UserClaimsPrincipalFactoryTest.cs index befed38dd9..bcf42f459d 100644 --- a/src/Identity/test/Identity.Test/UserClaimsPrincipalFactoryTest.cs +++ b/src/Identity/test/Identity.Test/UserClaimsPrincipalFactoryTest.cs @@ -30,22 +30,33 @@ namespace Microsoft.AspNetCore.Identity.Test } [Theory] - [InlineData(false, false, false)] - [InlineData(false, true, false)] - [InlineData(true, false, false)] - [InlineData(true, true, false)] - [InlineData(true, false, true)] - [InlineData(true, true, true)] - public async Task EnsureClaimsIdentityHasExpectedClaims(bool supportRoles, bool supportClaims, bool supportRoleClaims) + [InlineData(true, false, false, false)] + [InlineData(true, true, false, false)] + [InlineData(true, false, true, false)] + [InlineData(true, true, true, false)] + [InlineData(false, false, false, true)] + [InlineData(false, true, false, true)] + [InlineData(false, false, false, false)] + [InlineData(false, true, false, false)] + [InlineData(true, false, false, true)] + [InlineData(true, true, false, true)] + [InlineData(true, false, true, true)] + [InlineData(true, true, true, true)] + public async Task EnsureClaimsIdentityHasExpectedClaims(bool supportRoles, bool supportClaims, bool supportRoleClaims, bool supportsUserEmail) { // Setup var userManager = MockHelpers.MockUserManager(); var roleManager = MockHelpers.MockRoleManager(); - var user = new PocoUser { UserName = "Foo" }; + var user = new PocoUser { UserName = "Foo", Email = "foo@bar.com" }; userManager.Setup(m => m.SupportsUserClaim).Returns(supportClaims); userManager.Setup(m => m.SupportsUserRole).Returns(supportRoles); + userManager.Setup(m => m.SupportsUserEmail).Returns(supportsUserEmail); userManager.Setup(m => m.GetUserIdAsync(user)).ReturnsAsync(user.Id); userManager.Setup(m => m.GetUserNameAsync(user)).ReturnsAsync(user.UserName); + if (supportsUserEmail) + { + userManager.Setup(m => m.GetEmailAsync(user)).ReturnsAsync(user.Email); + } var roleClaims = new[] { "Admin", "Local" }; if (supportRoles) { @@ -90,6 +101,7 @@ namespace Microsoft.AspNetCore.Identity.Test Assert.Contains( claims, c => c.Type == manager.Options.ClaimsIdentity.UserNameClaimType && c.Value == user.UserName); Assert.Contains(claims, c => c.Type == manager.Options.ClaimsIdentity.UserIdClaimType && c.Value == user.Id); + Assert.Equal(supportsUserEmail, claims.Any(c => c.Type == manager.Options.ClaimsIdentity.EmailClaimType && c.Value == user.Email)); Assert.Equal(supportRoles, claims.Any(c => c.Type == manager.Options.ClaimsIdentity.RoleClaimType && c.Value == "Admin")); Assert.Equal(supportRoles, claims.Any(c => c.Type == manager.Options.ClaimsIdentity.RoleClaimType && c.Value == "Local")); foreach (var cl in userClaims)