Esempio n. 1
0
        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);
		}
Esempio n. 8
0
        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;
                    }
                }
            }
        }
Esempio n. 10
0
        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);
            }
        }
Esempio n. 11
0
        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);
        }
Esempio n. 21
0
        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);
            }
        }