protected internal virtual async Task <bool> ClaimsAreEqualAsync(IClaimBuilderCollection firstClaims, IList <Claim> secondClaims) { await Task.CompletedTask; if (firstClaims == null) { return(secondClaims == null); } if (secondClaims == null) { return(false); } if (firstClaims.Count != secondClaims.Count) { return(false); } foreach (var firstClaim in firstClaims) { if (!secondClaims.Any(secondClaim => string.Equals(firstClaim.Type, secondClaim.Type, StringComparison.OrdinalIgnoreCase) && string.Equals(firstClaim.Value, secondClaim.Value, StringComparison.Ordinal))) { return(false); } } return(true); }
public static void Add(this IClaimBuilderCollection claimBuilderCollection, string issuer, string originalIssuer, string type, string value, string valueType) { if (claimBuilderCollection == null) { throw new ArgumentNullException(nameof(claimBuilderCollection)); } var claimBuilder = claimBuilderCollection.CreateItem(); claimBuilder.Issuer = issuer; claimBuilder.OriginalIssuer = originalIssuer; claimBuilder.Type = type; claimBuilder.Value = value; claimBuilder.ValueType = valueType; claimBuilderCollection.Add(claimBuilder); }
protected internal virtual async Task ConvertToJwtClaimsAsync(IClaimBuilderCollection claims) { if (claims == null) { throw new ArgumentNullException(nameof(claims)); } await Task.CompletedTask; foreach (var mapping in this.Facade.IdentityServer.CurrentValue.ClaimTypeMap) { foreach (var claim in claims) { if (string.Equals(mapping.Key.UrlDecodeColon(), claim.Type, StringComparison.OrdinalIgnoreCase)) { claim.Type = mapping.Value; } } } }
protected internal virtual void BuildClaims(X509Certificate2 certificate, IClaimBuilderCollection claimsBuilder) { if (certificate == null) { throw new ArgumentNullException(nameof(certificate)); } if (claimsBuilder == null) { throw new ArgumentNullException(nameof(claimsBuilder)); } claimsBuilder.Add(ClaimTypes.Dns, certificate.GetNameInfo(X509NameType.DnsName, false)); claimsBuilder.Add(ClaimTypes.Email, certificate.GetNameInfo(X509NameType.EmailName, false)); claimsBuilder.Add("issuer", certificate.Issuer); claimsBuilder.Add(ClaimTypes.Name, certificate.GetNameInfo(X509NameType.SimpleName, false)); claimsBuilder.Add(ClaimTypes.NameIdentifier, certificate.Thumbprint, ClaimValueTypes.Base64Binary); claimsBuilder.Add(ClaimTypes.SerialNumber, certificate.SerialNumber); claimsBuilder.Add(ClaimTypes.Thumbprint, certificate.Thumbprint, ClaimValueTypes.Base64Binary); claimsBuilder.Add(ClaimTypes.Upn, certificate.GetNameInfo(X509NameType.UpnName, false)); claimsBuilder.Add(ClaimTypes.Uri, certificate.GetNameInfo(X509NameType.UrlName, false)); claimsBuilder.Add(ClaimTypes.X500DistinguishedName, certificate.SubjectName.Name); }
public static void Decorate(this IAuthenticationDecorator authenticationDecorator, AuthenticateResult authenticateResult, string authenticationScheme, IClaimBuilderCollection claims, AuthenticationProperties properties) { if (authenticationDecorator == null) { throw new ArgumentNullException(nameof(authenticationDecorator)); } authenticationDecorator.DecorateAsync(authenticateResult, authenticationScheme, claims, properties).Wait(); }
protected internal virtual void AdjustIdentityProviderClaimIfNecessary(string authenticationScheme, IClaimBuilderCollection claims) { if (authenticationScheme == null) { throw new ArgumentNullException(nameof(authenticationScheme)); } if (claims == null) { throw new ArgumentNullException(nameof(claims)); } if (!this.AdjustIdentityProviderClaim) { return; } var identityProviderClaim = claims.FindFirstIdentityProviderClaim(); if (identityProviderClaim == null) { return; } if (string.Equals(authenticationScheme, identityProviderClaim.Value, StringComparison.OrdinalIgnoreCase)) { return; } identityProviderClaim.Value = authenticationScheme; identityProviderClaim.Issuer = identityProviderClaim.OriginalIssuer = null; }
public override async Task DecorateAsync(AuthenticateResult authenticateResult, string authenticationScheme, IClaimBuilderCollection claims, AuthenticationProperties properties) { if(authenticateResult == null) throw new ArgumentNullException(nameof(authenticateResult)); if(authenticateResult.Principal == null) throw new ArgumentException("The principal-property of the authenticate-result can not be null.", nameof(authenticateResult)); if(claims == null) throw new ArgumentNullException(nameof(claims)); foreach(var mapping in this.ClaimInclusionsMap.Values) { if(!this.TryGetSpecialSourceClaim(authenticateResult.Principal, mapping.Source, out var claim)) { var sourceClaim = this.GetSourceClaim(authenticateResult.Principal, mapping.Source); if(sourceClaim != null) claim = new ClaimBuilder(sourceClaim); } if(claim == null) continue; if(mapping.Destination != null) claim.Type = mapping.Destination; claims.Add(claim); } await base.DecorateAsync(authenticateResult, authenticationScheme, claims, properties).ConfigureAwait(false); }
protected internal virtual ClaimsPrincipal CreateClaimsPrincipal(string authenticationScheme, IClaimBuilderCollection claims) { if (claims == null) { throw new ArgumentNullException(nameof(claims)); } return(new ClaimsPrincipal(new ClaimsIdentity(claims.Build(), authenticationScheme, claims.FindFirstNameClaim()?.Type, null))); }
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); } }
public virtual async Task <UserEntity> ResolveUserAsync(IClaimBuilderCollection claims, string provider, string userIdentifier) { if (claims == null) { throw new ArgumentNullException(nameof(claims)); } if (provider == null) { throw new ArgumentNullException(nameof(provider)); } if (userIdentifier == null) { throw new ArgumentNullException(nameof(userIdentifier)); } var user = await this.GetUserAsync(provider, userIdentifier); var userClaims = (user != null ? await this.UserManager.GetClaimsAsync(user) : null) ?? new List <Claim>(); if (user != null && await this.ClaimsAreEqualAsync(claims, userClaims)) { return(user); } var autoSaveChanges = this.UserManager.Store.AutoSaveChanges; this.UserManager.Store.AutoSaveChanges = true; var userExists = user != null; try { if (!userExists) { user = new UserEntity { UserName = Guid.NewGuid().ToString() }; var identityResult = await this.UserManager.CreateAsync(user); if (!identityResult.Succeeded) { throw new InvalidOperationException($"Could not create user: {await this.CreateErrorMessageAsync(identityResult)}"); } identityResult = await this.UserManager.AddLoginAsync(user, new UserLoginInfo(provider, userIdentifier, provider)); if (!identityResult.Succeeded) { throw new InvalidOperationException($"Could not add login for user: {await this.CreateErrorMessageAsync(identityResult)}"); } } await this.SaveClaimsAsync(claims, user); return(user); } finally { this.UserManager.Store.AutoSaveChanges = autoSaveChanges; } }
public static void Add(this IClaimBuilderCollection claimBuilderCollection, string type, string value) { claimBuilderCollection.Add(type, value, null); }
public static void Add(this IClaimBuilderCollection claimBuilderCollection, string issuer, string type, string value, string valueType) { claimBuilderCollection.Add(issuer, null, type, value, valueType); }
public override async Task DecorateAsync(AuthenticateResult authenticateResult, string authenticationScheme, IClaimBuilderCollection claims, AuthenticationProperties properties) { try { if (authenticateResult == null) { throw new ArgumentNullException(nameof(authenticateResult)); } if (claims == null) { throw new ArgumentNullException(nameof(claims)); } if (properties == null) { throw new ArgumentNullException(nameof(properties)); } await base.DecorateAsync(authenticateResult, authenticationScheme, claims, properties).ConfigureAwait(false); // If the external provider issued an id_token, we'll keep it for sign-out. var identityToken = authenticateResult.Properties.GetTokenValue(OidcConstants.TokenTypes.IdentityToken); if (identityToken != null) { properties.StoreTokens(new[] { new AuthenticationToken { Name = OidcConstants.TokenTypes.IdentityToken, Value = identityToken } }); } } catch (Exception exception) { const string message = "Could not decorate authentication-callback."; this.Logger.LogErrorIfEnabled(exception, message); throw new InvalidOperationException(message, exception); } }
public override async Task DecorateAsync(AuthenticateResult authenticateResult, string authenticationScheme, IClaimBuilderCollection claims, AuthenticationProperties properties) { try { var certificate = await this.HttpContextAccessor.HttpContext.Connection.GetClientCertificateAsync().ConfigureAwait(false); if (certificate == null) { this.Logger.LogErrorIfEnabled("There is not client-certificate connected."); return; } } catch (Exception exception) { const string message = "Could not decorate certificate-authentication."; this.Logger.LogErrorIfEnabled(exception, message); throw new InvalidOperationException(message, exception); } }
protected internal virtual async Task <ExtendedIdentityServerUser> ResolveUserAsync(string authenticationScheme, IClaimBuilderCollection claims) { if (claims == null) { throw new ArgumentNullException(nameof(claims)); } claims = claims.Clone(); var uniqueIdentifierClaim = claims.FindFirstUniqueIdentifierClaim(); if (uniqueIdentifierClaim == null) { throw new InvalidOperationException($"There is no unique-identifier-claim for authentication-scheme \"{authenticationScheme}\"."); } var uniqueIdentifier = uniqueIdentifierClaim.Value; claims.Remove(uniqueIdentifierClaim); var identityProviderClaim = claims.FindFirstIdentityProviderClaim(); var identityProvider = identityProviderClaim?.Value ?? authenticationScheme; if (identityProviderClaim != null) { claims.Remove(identityProviderClaim); } var user = await this.Facade.Identity.ResolveUserAsync(claims, identityProvider, uniqueIdentifier); var nameClaim = claims.FindFirstNameClaim(); var name = nameClaim?.Value; if (nameClaim != null) { claims.Remove(nameClaim); } return(new ExtendedIdentityServerUser(user.Id) { AdditionalClaims = claims.Build(), DisplayName = name, IdentityProvider = identityProvider, ProviderUserId = uniqueIdentifier }); }
public override async Task DecorateAsync(AuthenticateResult authenticateResult, string authenticationScheme, IClaimBuilderCollection claims, AuthenticationProperties properties) { if (authenticateResult == null) { throw new ArgumentNullException(nameof(authenticateResult)); } if (authenticateResult.Principal == null) { throw new ArgumentException("The principal-property of the authenticate-result can not be null.", nameof(authenticateResult)); } if (claims == null) { throw new ArgumentNullException(nameof(claims)); } foreach (var claim in authenticateResult.Principal.Claims) { if (!this.ClaimTypeExclusions.Contains(claim.Type)) { claims.Add(new ClaimBuilder(claim)); } } await base.DecorateAsync(authenticateResult, authenticationScheme, claims, properties).ConfigureAwait(false); }
public virtual async Task DecorateAsync(AuthenticateResult authenticateResult, string authenticationScheme, IClaimBuilderCollection claims, AuthenticationProperties properties) { this.AddAuthenticationSchemeAsIdentityProviderClaimIfNecessary(authenticationScheme, claims); this.AdjustIdentityProviderClaimIfNecessary(authenticationScheme, claims); await Task.CompletedTask.ConfigureAwait(false); }
public virtual async Task DecorateAsync(AuthenticateResult authenticateResult, string authenticationScheme, IClaimBuilderCollection claims, AuthenticationProperties properties) { try { if (authenticateResult == null) { throw new ArgumentNullException(nameof(authenticateResult)); } if (claims == null) { throw new ArgumentNullException(nameof(claims)); } if (!this.IsActiveLoginAuthenticationScheme(authenticationScheme)) { return; } var identityProviderClaim = claims.FindFirstIdentityProviderClaim(); if (identityProviderClaim == null) { identityProviderClaim = new ClaimBuilder { Type = ExtendedClaimTypes.IdentityProvider, }; claims.Add(identityProviderClaim); } identityProviderClaim.Issuer = identityProviderClaim.OriginalIssuer = null; identityProviderClaim.Value = this.IdentityProvider; var originalIdentityProviderClaim = authenticateResult.Principal.Claims.FindFirstIdentityProviderClaim(); if (originalIdentityProviderClaim != null) { claims.Add(new ClaimBuilder(originalIdentityProviderClaim) { Type = this.OriginalIdentityProviderClaimType }); } await Task.CompletedTask.ConfigureAwait(false); } catch (Exception exception) { const string message = "Could not decorate active-login-callback."; this.Logger.LogErrorIfEnabled(exception, message); throw new InvalidOperationException(message, exception); } }
protected internal virtual void AddAuthenticationSchemeAsIdentityProviderClaimIfNecessary(string authenticationScheme, IClaimBuilderCollection claims) { if (authenticationScheme == null) { throw new ArgumentNullException(nameof(authenticationScheme)); } if (claims == null) { throw new ArgumentNullException(nameof(claims)); } if (!this.IncludeAuthenticationSchemeAsIdentityProviderClaim) { return; } var identityProviderClaim = claims.FindFirstIdentityProviderClaim(); if (identityProviderClaim != null) { return; } claims.Add(ExtendedClaimTypes.IdentityProvider, authenticationScheme); }
protected internal virtual async Task ResolveUniqueIdentifier(string authenticationScheme, IClaimBuilderCollection claims) { if (claims == null) { throw new ArgumentNullException(nameof(claims)); } var uniqueIdentifierClaim = claims.FindFirstUniqueIdentifierClaim(); if (uniqueIdentifierClaim == null) { throw new InvalidOperationException($"There is no unique-identifier-claim for authentication-scheme \"{authenticationScheme}\"."); } var identityProvider = claims.FindFirstIdentityProviderClaim()?.Value ?? authenticationScheme; uniqueIdentifierClaim.Value = this.GetOrCreateUniqueIdentifier(identityProvider, uniqueIdentifierClaim.Value); uniqueIdentifierClaim.Issuer = uniqueIdentifierClaim.OriginalIssuer = uniqueIdentifierClaim.ValueType = null; await Task.CompletedTask.ConfigureAwait(false); }
public override async Task DecorateAsync(AuthenticateResult authenticateResult, string authenticationScheme, IClaimBuilderCollection claims, AuthenticationProperties properties) { try { if (authenticateResult == null) { throw new ArgumentNullException(nameof(authenticateResult)); } if (authenticateResult.Principal == null) { throw new ArgumentException("The principal-property of the authenticate-result can not be null.", nameof(authenticateResult)); } if (!(authenticateResult.Principal is WindowsPrincipal)) { throw new ArgumentException("The principal is not a windows-principal.", nameof(authenticateResult)); } await base.DecorateAsync(authenticateResult, authenticationScheme, claims, properties).ConfigureAwait(false); if (this.AuthenticationOptions.Value.Windows.IncludeRoleClaims) { if (!(authenticateResult.Principal.Identity is WindowsIdentity windowsIdentity)) { this.Logger.LogWarningIfEnabled("The principal-identity is not a windows-identity. Roles will not be added as claims."); return; } // ReSharper disable All foreach (var role in windowsIdentity.Groups.Translate(typeof(NTAccount)).Cast <NTAccount>().Select(ntAccount => ntAccount.Value).OrderBy(value => value)) { claims.Add(authenticationScheme, ClaimTypes.Role, role, ClaimValueTypes.String); } // ReSharper restore All } } catch (Exception exception) { const string message = "Could not decorate windows-authentication."; this.Logger.LogErrorIfEnabled(exception, message); throw new InvalidOperationException(message, exception); } }