public async Task ClaimsAreEqualAsync_Test() { using (var context = new Context(databaseProvider: DatabaseProvider.Sqlite)) { var serviceProvider = context.ServiceProvider; var identityFacade = await this.CreateIdentityFacadeAsync(serviceProvider); Assert.IsTrue(await identityFacade.ClaimsAreEqualAsync(null, null)); Assert.IsFalse(await identityFacade.ClaimsAreEqualAsync(new ClaimBuilderCollection(), null)); Assert.IsFalse(await identityFacade.ClaimsAreEqualAsync(null, new List <Claim>())); var firstClaims = new ClaimBuilderCollection { new ClaimBuilder { Type = "Claim-type-1", Value = "Claim-value-1" } }; var secondClaims = new List <Claim> { new Claim("Claim-type-1", "Claim-value-1") }; Assert.IsTrue(await identityFacade.ClaimsAreEqualAsync(firstClaims, secondClaims)); secondClaims = new List <Claim> { new Claim("Claim-type-1", "Claim-value-2") }; Assert.IsFalse(await identityFacade.ClaimsAreEqualAsync(firstClaims, secondClaims)); } }
public virtual async Task <IActionResult> Windows(string authenticationScheme, string returnUrl) { returnUrl = await this.ResolveAndValidateAsync(authenticationScheme, AuthenticationSchemeKind.Windows, returnUrl); // Check if windows-authentication has already been requested and succeeded. var authenticateResult = await this.HttpContext.AuthenticateAsync(authenticationScheme); // ReSharper disable InvertIf if (authenticateResult?.Principal is WindowsPrincipal) { var decorators = (await this.Facade.DecorationLoader.GetAuthenticationDecoratorsAsync(authenticationScheme)).ToArray(); if (!decorators.Any()) { throw new InvalidOperationException($"There are no authentication-decorators for authentication-scheme \"{authenticationScheme}\"."); } var authenticationProperties = await this.CreateAuthenticationPropertiesAsync(authenticationScheme, returnUrl); var claims = new ClaimBuilderCollection(); foreach (var decorator in decorators) { await decorator.DecorateAsync(authenticateResult, authenticationScheme, claims, authenticationProperties); } await this.HttpContext.SignInAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme, this.CreateClaimsPrincipal(authenticationScheme, claims), authenticationProperties); return(this.Redirect(authenticationProperties.RedirectUri)); } // ReSharper restore InvertIf // Trigger windows-authentication. Since windows-authentication don't support the redirect uri, this URL is re-triggered when we call challenge. return(this.Challenge(authenticationScheme)); }
public void DecorateAsync_ShouldExcludeClaimsProperly() { var claims = new ClaimBuilderCollection { { "A-type", "A-value" }, { "B-type", "B-value" }, { "C-type", "C-value" }, { "D-type", "D-value" }, { "E-type", "E-value" } }; var authenticateResult = this.CreateAuthenticateResult(new ClaimsPrincipal(new ClaimsIdentity(claims.Build()))); var excludeClaimDecorator = this.CreateExcludeClaimDecorator(); excludeClaimDecorator.IncludeAuthenticationSchemeAsIdentityProviderClaim = false; excludeClaimDecorator.ClaimTypeExclusions.Add("A-type"); excludeClaimDecorator.ClaimTypeExclusions.Add("C-type"); excludeClaimDecorator.ClaimTypeExclusions.Add("E-type"); claims.Clear(); Assert.AreEqual(0, claims.Count); excludeClaimDecorator.DecorateAsync(authenticateResult, "Test", claims, null).Wait(); Assert.AreEqual(2, claims.Count); Assert.IsNotNull(claims.FirstOrDefault(claim => claim.Type == "B-type")); Assert.IsNotNull(claims.FirstOrDefault(claim => claim.Type == "D-type")); }
public virtual async Task <IActionResult> Certificate(string authenticationScheme, string returnUrl) { this.ValidateAuthenticationScheme(authenticationScheme, AuthenticationSchemeKind.Certificate); returnUrl = this.ResolveAndValidateReturnUrl(returnUrl); var authenticateResult = await this.HttpContext.AuthenticateAsync(authenticationScheme); if (!authenticateResult.Succeeded) { throw new InvalidOperationException("Authentication error.", authenticateResult.Failure); } var authenticationProperties = this.CreateAuthenticationProperties(returnUrl, authenticationScheme); var certificatePrincipal = authenticateResult.Principal; var decorators = (await this.DecorationLoader.GetAuthenticationDecoratorsAsync(authenticationScheme)).ToArray(); if (decorators.Any()) { var claims = new ClaimBuilderCollection(); foreach (var decorator in decorators) { await decorator.DecorateAsync(authenticateResult, authenticationScheme, claims, authenticationProperties); } certificatePrincipal = this.CreateClaimsPrincipal(authenticationScheme, claims); } await this.HttpContext.SignInAsync(this.AuthenticationOptions.Value.DefaultSignInScheme, certificatePrincipal, authenticationProperties); return(this.Redirect(authenticationProperties.RedirectUri)); }
public virtual async Task <IActionResult> Callback() { var authenticateResult = await this.HttpContext.AuthenticateAsync(this.AuthenticationOptions.Value.DefaultSignInScheme); if (!authenticateResult.Succeeded) { throw new InvalidOperationException("Authentication error.", authenticateResult.Failure); } var returnUrl = this.ResolveAndValidateReturnUrl(authenticateResult.Properties.Items["returnUrl"]); var authenticationScheme = authenticateResult.Properties.Items["scheme"]; var decorators = (await this.DecorationLoader.GetCallbackDecoratorsAsync(authenticationScheme)).ToArray(); if (!decorators.Any()) { throw new InvalidOperationException($"There are no callback-decorators for authentication-scheme \"{authenticationScheme}\"."); } var authenticationProperties = new AuthenticationProperties(); var claims = new ClaimBuilderCollection(); foreach (var decorator in decorators) { await decorator.DecorateAsync(authenticateResult, authenticationScheme, claims, authenticationProperties); } await this.ResolveUniqueIdentifier(authenticationScheme, claims); await this.HttpContext.SignInAsync(this.AuthenticationOptions.Value.DefaultScheme, this.CreateClaimsPrincipal(authenticationScheme, claims), authenticationProperties); await this.HttpContext.SignOutAsync(this.AuthenticationOptions.Value.DefaultSignInScheme); return(this.Redirect(returnUrl)); }
public virtual async Task <IActionResult> Callback() { this.Logger.LogDebugIfEnabled("Callback: starting..."); var authenticateResult = await this.HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme); if (!authenticateResult.Succeeded) { throw new InvalidOperationException("Authentication error.", authenticateResult.Failure); } var returnUrl = this.ResolveAndValidateReturnUrl(authenticateResult.Properties.Items[AuthenticationKeys.ReturnUrl]); var authenticationScheme = authenticateResult.Properties.Items[AuthenticationKeys.Scheme]; await this.ValidateAuthenticationSchemeForClientAsync(authenticationScheme, returnUrl); this.Logger.LogDebugIfEnabled($"Callback: authentication-sheme = \"{authenticationScheme}\", claims received = \"{string.Join(", ", authenticateResult.Principal.Claims.Select(claim => claim.Type))}\"."); var decorators = (await this.Facade.DecorationLoader.GetCallbackDecoratorsAsync(authenticationScheme)).ToArray(); if (!decorators.Any()) { throw new InvalidOperationException($"There are no callback-decorators for authentication-scheme \"{authenticationScheme}\"."); } var authenticationProperties = new AuthenticationProperties(); var claims = new ClaimBuilderCollection(); foreach (var decorator in decorators) { await decorator.DecorateAsync(authenticateResult, authenticationScheme, claims, authenticationProperties); this.Logger.LogDebugIfEnabled($"Callback: {decorator.GetType().FullName}.DecorateAsync claims = \"{string.Join(", ", claims.Select(claim => claim.Type))}\"."); } await this.ConvertToJwtClaimsAsync(claims); this.Logger.LogDebugIfEnabled($"Callback: converted to jwt-claims = \"{string.Join(", ", claims.Select(claim => claim.Type))}\"."); var user = await this.ResolveUserAsync(authenticationScheme, claims); await this.HttpContext.SignInAsync(user, authenticationProperties); await this.HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme); var authorizationRequest = await this.Facade.Interaction.GetAuthorizationContextAsync(returnUrl); await this.Facade.Events.RaiseAsync(new UserLoginSuccessEvent(user.IdentityProvider, user.ProviderUserId, user.SubjectId, user.DisplayName, true, authorizationRequest?.Client.ClientId)); if (authorizationRequest != null && authorizationRequest.IsNativeClient()) { return(await this.Redirect(returnUrl, this.Facade.IdentityServer.CurrentValue.Redirection.SecondsBeforeRedirect)); } return(this.Redirect(returnUrl)); }
public void DecorateAsync_IfIncludeAuthenticationSchemeAsIdentityProviderClaim_And_IfTheClaimNotAlreadyExists_ShouldAddTheClaim() { const string authenticationScheme = "Authentication-scheme"; var authenticationDecorator = this.CreateAuthenticationDecorator(); var claims = new ClaimBuilderCollection(); authenticationDecorator.DecorateAsync(null, authenticationScheme, claims, null).Wait(); Assert.AreEqual(authenticationScheme, claims.First(claim => string.Equals(ExtendedClaimTypes.IdentityProvider, claim.Type, StringComparison.OrdinalIgnoreCase)).Value); }
public void DecorateAsync_IfIncludeAuthenticationSchemeAsIdentityProviderClaimIsFalse_ShouldNotAddTheClaim() { const string authenticationScheme = "Authentication-scheme"; var authenticationDecorator = this.CreateAuthenticationDecorator(); var claims = new ClaimBuilderCollection(); authenticationDecorator.IncludeAuthenticationSchemeAsIdentityProviderClaim = false; authenticationDecorator.DecorateAsync(null, authenticationScheme, claims, null).Wait(); Assert.IsFalse(claims.Any()); }
public virtual async Task <IActionResult> Certificate(string authenticationScheme, string returnUrl) { returnUrl = await this.ResolveAndValidateAsync(authenticationScheme, AuthenticationSchemeKind.Certificate, returnUrl); var certificate = await this.HttpContext.Connection.GetClientCertificateAsync(); if (certificate == null) { var request = this.HttpContext.Request; var certificateAuthenticationHost = await this.GetCertificateAuthenticationHostAsync(); var certificateAuthenticationUrl = $"{request.Scheme}://{certificateAuthenticationHost}{request.Path}{request.QueryString}"; var host = request.Host.Value; if (!string.Equals(certificateAuthenticationHost, host, StringComparison.OrdinalIgnoreCase)) { return(this.Redirect(certificateAuthenticationUrl)); } throw new InvalidOperationException("Authentication error.", new InvalidOperationException($"There is no client-certificate connected for url \"{certificateAuthenticationUrl}\".")); } var authenticateResult = await this.HttpContext.AuthenticateAsync(authenticationScheme); if (!authenticateResult.Succeeded) { throw new InvalidOperationException("Authentication error.", authenticateResult.Failure); } var authenticationProperties = await this.CreateAuthenticationPropertiesAsync(authenticationScheme, returnUrl); var certificatePrincipal = authenticateResult.Principal; var decorators = (await this.Facade.DecorationLoader.GetAuthenticationDecoratorsAsync(authenticationScheme)).ToArray(); if (decorators.Any()) { var claims = new ClaimBuilderCollection(); foreach (var decorator in decorators) { await decorator.DecorateAsync(authenticateResult, authenticationScheme, claims, authenticationProperties); } certificatePrincipal = this.CreateClaimsPrincipal(authenticationScheme, claims); } await this.HttpContext.SignInAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme, certificatePrincipal, authenticationProperties); return(this.Redirect(authenticationProperties.RedirectUri)); }
public void DecorateAsync_IfIncludeAuthenticationSchemeAsIdentityProviderClaim_And_IfTheClaimAlreadyExists_ShouldNotAddTheClaim() { const string authenticationScheme = "Authentication-scheme"; var authenticationDecorator = this.CreateAuthenticationDecorator(); var claims = new ClaimBuilderCollection { { ExtendedClaimTypes.IdentityProvider, authenticationScheme } }; Assert.AreEqual(1, claims.Count); authenticationDecorator.DecorateAsync(null, authenticationScheme, claims, null).Wait(); Assert.AreEqual(1, claims.Count); }
public void DecorateAsync_CurrentWindowsPrincipal_WithRoles_Test() { const string authenticationScheme = "Test-authentication-scheme"; var claims = new ClaimBuilderCollection(); var windowsIdentity = WindowsIdentity.GetCurrent(); var principal = new WindowsPrincipal(windowsIdentity); var authenticateResult = this.CreateAuthenticateResult(principal); var windowsAuthenticationDecorator = this.CreateWindowsAuthenticationDecorator(new ExtendedAuthenticationOptions {Windows = {IncludeRoleClaims = true}}, Mock.Of<ILoggerFactory>()); windowsAuthenticationDecorator.DecorateAsync(authenticateResult, authenticationScheme, claims, null).Wait(); // ReSharper disable PossibleNullReferenceException Assert.AreEqual(8 + windowsIdentity.Groups.Count, claims.Count); // ReSharper restore PossibleNullReferenceException }
public void DecorateAsync_CurrentWindowsPrincipal_WithoutRoles_Test() { const string authenticationScheme = "Test-authentication-scheme"; var claims = new ClaimBuilderCollection(); var windowsIdentity = WindowsIdentity.GetCurrent(); var principal = new WindowsPrincipal(windowsIdentity); var authenticateResult = this.CreateAuthenticateResult(principal); var windowsAuthenticationDecorator = this.CreateWindowsAuthenticationDecorator(); windowsAuthenticationDecorator.DecorateAsync(authenticateResult, authenticationScheme, claims, null).Wait(); Assert.AreEqual(8, claims.Count); Assert.AreEqual(windowsIdentity.AuthenticationType, claims.First(claim => string.Equals(claim.Type, ClaimTypes.AuthenticationMethod, StringComparison.Ordinal)).Value); Assert.AreEqual(windowsIdentity.Name, claims.First(claim => string.Equals(claim.Type, ClaimTypes.Name, StringComparison.Ordinal)).Value); Assert.AreEqual(windowsIdentity.FindFirst(ClaimTypes.PrimarySid).Value, claims.First(claim => string.Equals(claim.Type, ClaimTypes.NameIdentifier, StringComparison.Ordinal)).Value); Assert.AreEqual(windowsIdentity.FindFirst(ClaimTypes.PrimarySid).Value, claims.First(claim => string.Equals(claim.Type, ClaimTypes.PrimarySid, StringComparison.Ordinal)).Value); Assert.AreEqual(windowsIdentity.Name, claims.First(claim => string.Equals(claim.Type, ClaimTypes.WindowsAccountName, StringComparison.Ordinal)).Value); Assert.AreEqual(authenticationScheme, claims.First(claim => string.Equals(claim.Type, ExtendedClaimTypes.IdentityProvider, StringComparison.Ordinal)).Value); }
public void DecorateAsync_ShouldIncludeAllPrincipalClaimsByDefault() { var claims = new ClaimBuilderCollection { { "A-type", "A-value" }, { "B-type", "B-value" }, { "C-type", "C-value" } }; var authenticateResult = this.CreateAuthenticateResult(new ClaimsPrincipal(new ClaimsIdentity(claims.Build()))); var excludeClaimDecorator = this.CreateExcludeClaimDecorator(); excludeClaimDecorator.IncludeAuthenticationSchemeAsIdentityProviderClaim = false; claims.Clear(); Assert.AreEqual(0, claims.Count); excludeClaimDecorator.DecorateAsync(authenticateResult, "Test", claims, null).Wait(); Assert.AreEqual(3, claims.Count); }
public override async Task DecorateAsync(AuthenticateResult authenticateResult, string authenticationScheme, IClaimBuilderCollection claims, AuthenticationProperties properties) { if (claims == null) { throw new ArgumentNullException(nameof(claims)); } if (!claims.Any()) { await base.DecorateAsync(authenticateResult, authenticationScheme, claims, properties).ConfigureAwait(false); } else { var activeDirectoryClaims = new ClaimBuilderCollection(); await base.DecorateAsync(authenticateResult, authenticationScheme, activeDirectoryClaims, properties).ConfigureAwait(false); foreach (var activeDirectoryClaim in activeDirectoryClaims) { for (var i = 0; i < claims.Count; i++) { var claim = claims[i]; if (!string.Equals(activeDirectoryClaim.Type, claim.Type, StringComparison.OrdinalIgnoreCase)) { continue; } if (string.Equals(activeDirectoryClaim.Value, claim.Value, StringComparison.Ordinal)) { continue; } claims[i] = activeDirectoryClaim; } } } }
protected internal virtual async Task SaveClaimsAsync(IClaimBuilderCollection claims, UserEntity user) { var logPrefix = $"{this.GetType().FullName}.{nameof(this.SaveClaimsAsync)}:"; this.Logger.LogDebugIfEnabled($"{logPrefix} user-id = {user?.Id.ToStringRepresentation()}, starting..."); if (claims == null) { throw new ArgumentNullException(nameof(claims)); } if (user == null) { throw new ArgumentNullException(nameof(user)); } try { var comparer = StringComparer.Ordinal; var sortedClaims = new ClaimBuilderCollection(); foreach (var claim in claims.OrderBy(claim => claim.Type, comparer).ThenBy(claim => claim.Value, comparer)) { sortedClaims.Add(new ClaimBuilder { Type = claim.Type, Value = claim.Value }); } var i = 0; var userClaimsToRemove = new List <IdentityUserClaim <string> >(); foreach (var userClaim in this.DatabaseContext.UserClaims.Where(claim => claim.UserId == user.Id).OrderBy(claim => claim.Id)) { if (sortedClaims.Count < i + 1) { userClaimsToRemove.Add(userClaim); } else { var claim = sortedClaims[i]; const StringComparison comparison = StringComparison.OrdinalIgnoreCase; if (!string.Equals(claim.Type, userClaim.ClaimType, comparison) || !string.Equals(claim.Value, userClaim.ClaimValue, comparison)) { this.Logger.LogDebugIfEnabled($"{logPrefix} changing claim with id {userClaim.Id.ToStringRepresentation()} from type {userClaim.ClaimType.ToStringRepresentation()} to type {claim.Type.ToStringRepresentation()} and from value {userClaim.ClaimValue.ToStringRepresentation()} to value {claim.Value.ToStringRepresentation()}."); userClaim.ClaimType = claim.Type; userClaim.ClaimValue = claim.Value; } } i++; } if (userClaimsToRemove.Any()) { this.Logger.LogDebugIfEnabled($"{logPrefix} removing {userClaimsToRemove.Count} claims with id's: {string.Join(", ", userClaimsToRemove.Select(userClaim => userClaim.Id))}"); this.DatabaseContext.UserClaims.RemoveRange(userClaimsToRemove); } else if (sortedClaims.Count > i) { foreach (var claim in sortedClaims.Skip(i)) { var claimToAdd = new IdentityUserClaim <string> { ClaimType = claim.Type, ClaimValue = claim.Value, UserId = user.Id }; this.Logger.LogDebugIfEnabled($"{logPrefix} adding claim with type {claim.Type.ToStringRepresentation()} and value {claim.Value.ToStringRepresentation()}."); await this.DatabaseContext.UserClaims.AddAsync(claimToAdd); } } var savedChanges = await this.DatabaseContext.SaveChangesAsync(); this.Logger.LogDebugIfEnabled($"{logPrefix} saved changes = {savedChanges}"); } catch (Exception exception) { throw new InvalidOperationException("Could not save claims for user.", exception); } }
protected internal virtual async Task ResolveUserAsync_IfTheUserAlreadyExistsAndTheDatabaseClaimsHaveBeenExplicitlyChanged_ShouldCorrectClaims(DatabaseProvider databaseProvider) { var claims = new ClaimBuilderCollection { new ClaimBuilder { Type = "First-type", Value = "First-value" }, new ClaimBuilder { Type = "Second-type", Value = "Second-value" }, new ClaimBuilder { Type = "Third-type", Value = "Third-value" } }; const string provider = "Provider"; const string userIdentifier = "User-identifier"; using (var context = new Context(databaseProvider: databaseProvider)) { var serviceProvider = context.ServiceProvider; await DatabaseHelper.MigrateDatabaseAsync(serviceProvider); var identityFacade = await this.CreateIdentityFacadeAsync(serviceProvider); var user = await identityFacade.ResolveUserAsync(claims, provider, userIdentifier); Assert.IsNotNull(user); } using (var context = new Context(databaseProvider: databaseProvider)) { var serviceProvider = context.ServiceProvider; var identityContext = serviceProvider.GetRequiredService <IdentityContext>(); Assert.IsNotNull(identityContext); Assert.AreEqual(3, identityContext.UserClaims.Count()); Assert.AreEqual("First-type", (await identityContext.UserClaims.FindAsync(1)).ClaimType); Assert.AreEqual("First-value", (await identityContext.UserClaims.FindAsync(1)).ClaimValue); Assert.AreEqual("Second-type", (await identityContext.UserClaims.FindAsync(2)).ClaimType); Assert.AreEqual("Second-value", (await identityContext.UserClaims.FindAsync(2)).ClaimValue); Assert.AreEqual("Third-type", (await identityContext.UserClaims.FindAsync(3)).ClaimType); Assert.AreEqual("Third-value", (await identityContext.UserClaims.FindAsync(3)).ClaimValue); } using (var context = new Context(databaseProvider: databaseProvider)) { var serviceProvider = context.ServiceProvider; var identityContext = serviceProvider.GetRequiredService <IdentityContext>(); var thirdClaim = await identityContext.UserClaims.FindAsync(3); thirdClaim.ClaimType = "Second-type"; thirdClaim.ClaimValue = "Second-value"; Assert.AreEqual(1, await identityContext.SaveChangesAsync()); } using (var context = new Context(databaseProvider: databaseProvider)) { var serviceProvider = context.ServiceProvider; var identityContext = serviceProvider.GetRequiredService <IdentityContext>(); Assert.IsNotNull(identityContext); Assert.AreEqual(3, identityContext.UserClaims.Count()); Assert.AreEqual("First-type", (await identityContext.UserClaims.FindAsync(1)).ClaimType); Assert.AreEqual("First-value", (await identityContext.UserClaims.FindAsync(1)).ClaimValue); Assert.AreEqual("Second-type", (await identityContext.UserClaims.FindAsync(2)).ClaimType); Assert.AreEqual("Second-value", (await identityContext.UserClaims.FindAsync(2)).ClaimValue); Assert.AreEqual("Second-type", (await identityContext.UserClaims.FindAsync(3)).ClaimType); Assert.AreEqual("Second-value", (await identityContext.UserClaims.FindAsync(3)).ClaimValue); } using (var context = new Context(databaseProvider: databaseProvider)) { var serviceProvider = context.ServiceProvider; var identityFacade = await this.CreateIdentityFacadeAsync(serviceProvider); var user = await identityFacade.ResolveUserAsync(claims, provider, userIdentifier); Assert.IsNotNull(user); } using (var context = new Context(databaseProvider: databaseProvider)) { var serviceProvider = context.ServiceProvider; var identityContext = serviceProvider.GetRequiredService <IdentityContext>(); Assert.IsNotNull(identityContext); Assert.AreEqual(3, identityContext.UserClaims.Count()); Assert.AreEqual("First-type", (await identityContext.UserClaims.FindAsync(1)).ClaimType); Assert.AreEqual("First-value", (await identityContext.UserClaims.FindAsync(1)).ClaimValue); Assert.AreEqual("Second-type", (await identityContext.UserClaims.FindAsync(2)).ClaimType); Assert.AreEqual("Second-value", (await identityContext.UserClaims.FindAsync(2)).ClaimValue); Assert.AreEqual("Third-type", (await identityContext.UserClaims.FindAsync(3)).ClaimType); Assert.AreEqual("Third-value", (await identityContext.UserClaims.FindAsync(3)).ClaimValue); } }
protected internal virtual async Task ResolveUserAsync_IfTheUserAlreadyExists_ShouldUpdateClaims(DatabaseProvider databaseProvider) { const string claimType = "Claim-type"; const string provider = "Provider"; const string subject = "Subject"; using (var context = new Context(databaseProvider: databaseProvider)) { var serviceProvider = context.ServiceProvider; await DatabaseHelper.MigrateDatabaseAsync(serviceProvider); var claimValue = "Initial value"; var claims = new ClaimBuilderCollection { new ClaimBuilder { Type = claimType, Value = claimValue } }; var identityFacade = await this.CreateIdentityFacadeAsync(serviceProvider); var user = await identityFacade.ResolveUserAsync(claims, provider, subject); Assert.IsNotNull(user); var userClaims = await identityFacade.UserManager.GetClaimsAsync(user); Assert.IsNotNull(userClaims); Assert.AreEqual(1, userClaims.Count); Assert.AreEqual(claimType, userClaims[0].Type); Assert.AreEqual(claimValue, userClaims[0].Value); claimValue = "New value"; claims[0].Value = claimValue; user = await identityFacade.ResolveUserAsync(claims, provider, subject); Assert.IsNotNull(user); userClaims = await identityFacade.UserManager.GetClaimsAsync(user); Assert.IsNotNull(userClaims); Assert.AreEqual(1, userClaims.Count); Assert.AreEqual(claimType, userClaims[0].Type); Assert.AreEqual(claimValue, userClaims[0].Value); claims = new ClaimBuilderCollection { new ClaimBuilder { Type = "1", Value = "1" }, new ClaimBuilder { Type = "1", Value = "2" }, new ClaimBuilder { Type = "1", Value = "3" }, new ClaimBuilder { Type = "1", Value = "4" } }; user = await identityFacade.ResolveUserAsync(claims, provider, subject); userClaims = await identityFacade.UserManager.GetClaimsAsync(user); Assert.IsNotNull(userClaims); Assert.AreEqual(4, userClaims.Count); claims.Add(new ClaimBuilder { Type = "2", Value = "1" }); user = await identityFacade.ResolveUserAsync(claims, provider, subject); userClaims = await identityFacade.UserManager.GetClaimsAsync(user); Assert.IsNotNull(userClaims); Assert.AreEqual(5, userClaims.Count); claims.RemoveAt(4); claims.RemoveAt(3); for (var i = 0; i < claims.Count; i++) { var claim = claims[i]; claim.Type = $"{i + 1}"; claim.Value += " (changed)"; } user = await identityFacade.ResolveUserAsync(claims, provider, subject); userClaims = await identityFacade.UserManager.GetClaimsAsync(user); Assert.IsNotNull(userClaims); Assert.AreEqual(3, userClaims.Count); Assert.AreEqual(userClaims[0].Type, "1"); Assert.AreEqual(userClaims[0].Value, "1 (changed)"); Assert.AreEqual(userClaims[1].Type, "2"); Assert.AreEqual(userClaims[1].Value, "2 (changed)"); Assert.AreEqual(userClaims[2].Type, "3"); Assert.AreEqual(userClaims[2].Value, "3 (changed)"); } }