Example #1
0
        /// <summary>
        /// Create an authorization context
        /// </summary>
        public ClaimsPrincipal CreateClaimsPrincipal()
        {
            if (!this.m_isAuthenticated)
            {
                throw new SecurityException("Principal is not authenticated");
            }

            try
            {
                // System claims
                List <Claim> claims = new List <Claim>(
                    this.m_roles.Select(r => new Claim(ClaimsIdentity.DefaultRoleClaimType, r.Name))
                    )
                {
                    new Claim(ClaimTypes.Authentication, nameof(SqlClaimsIdentity)),
                    new Claim(ClaimTypes.AuthorizationDecision, this.m_isAuthenticated ? "GRANT" : "DENY"),
                    new Claim(ClaimTypes.AuthenticationInstant, this.IssuedOn.ToString("o")), // TODO: Fix this
                    new Claim(ClaimTypes.AuthenticationMethod, this.m_authenticationType),
                    new Claim(ClaimTypes.Expiration, this.Expiry.ToString("o")),              // TODO: Move this to configuration
                    new Claim(ClaimTypes.Name, this.m_securityUser.UserName),
                    new Claim(ClaimTypes.Sid, this.m_securityUser.UserId.ToString()),
                    new Claim(ClaimTypes.NameIdentifier, this.m_securityUser.UserId.ToString()),
                    new Claim(ClaimTypes.Actor, this.m_securityUser.UserClass.ToString()),
                };

                if (this.m_securityUser.Email != null && this.m_securityUser.EmailConfirmed)
                {
                    claims.Add(new Claim(ClaimTypes.Email, this.m_securityUser.Email));
                }

                // TODO: Demographic data for the user
                var retVal = new ClaimsPrincipal(
                    new ClaimsIdentity[] { new ClaimsIdentity(this, claims.AsReadOnly()) }
                    );
                s_traceSource.TraceInformation("Created security principal from identity {0} > {1}", this, SqlClaimsIdentity.PrincipalToString(retVal));
                return(retVal);
            }
            catch (Exception e)
            {
                s_traceSource.TraceEvent(TraceEventType.Error, e.HResult, e.ToString());
                throw new Exception("Creating principal from identity failed", e);
            }
        }
Example #2
0
        /// <summary>
        /// Creates a principal based on username and password
        /// </summary>
        internal static SqlClaimsIdentity Create(String userName, String password)
        {
            try
            {
                if (userName == AuthenticationContext.AnonymousPrincipal.Identity.Name ||
                    userName == AuthenticationContext.SystemPrincipal.Identity.Name)
                {
                    throw new PolicyViolationException(PermissionPolicyIdentifiers.Login, PolicyDecisionOutcomeType.Deny);
                }

                Guid?userId = Guid.Empty;

                using (var dataContext = new Data.ModelDataContext(s_configuration.ReadWriteConnectionString))
                {
                    // Attempt to get a user
                    var hashingService = ApplicationContext.Current.GetService <IPasswordHashingService>();

                    var passwordHash = hashingService.EncodePassword(password);
                    dataContext.sp_Authenticate(userName, passwordHash, 3, ref userId);
                }

                using (var dataContext = new Data.ModelDataContext(s_configuration.ReadonlyConnectionString))
                {
                    var user         = dataContext.SecurityUsers.SingleOrDefault(u => u.UserId == userId);
                    var userIdentity = new SqlClaimsIdentity(user, true)
                    {
                        m_authenticationType = "Password"
                    };

                    // Is user allowed to login?
                    if (user.UserClass == UserClassKeys.HumanUser)
                    {
                        new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PermissionPolicyIdentifiers.Login, new GenericPrincipal(userIdentity, null)).Demand();
                    }
                    else if (user.UserClass == UserClassKeys.ApplicationUser)
                    {
                        new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PermissionPolicyIdentifiers.LoginAsService, new GenericPrincipal(userIdentity, null)).Demand();
                    }

                    return(userIdentity);
                }
            }
            catch (AuthenticationException)
            {
                // TODO: Audit this
                throw;
            }
            catch (SecurityException)
            {
                // TODO: Audit this
                throw;
            }
            catch (SqlException e)
            {
                switch (e.Number)
                {
                case 51900:
                    throw new AuthenticationException("Account is locked");

                case 51901:
                    throw new AuthenticationException("Invalid username/password");

                case 51902:
                    throw new AuthenticationException("User requires two-factor authentication");

                default:
                    throw e;
                }
            }
            catch (Exception e)
            {
                s_traceSource.TraceEvent(TraceEventType.Error, e.HResult, e.ToString());
                throw new Exception("Creating identity failed", e);
            }
        }
Example #3
0
        /// <summary>
        /// Creates a principal based on username and password
        /// </summary>
        internal static SqlClaimsIdentity Create(byte[] refreshToken)
        {
            try
            {
                Guid?userId = Guid.Empty;

                using (var dataContext = new Data.ModelDataContext(s_configuration.ReadWriteConnectionString))
                {
                    // Attempt to get a user
                    var secretClaim = dataContext.SecurityUserClaims.FirstOrDefault(o => o.ClaimType == SqlServerConstants.RefreshSecretClaimType && o.ClaimValue == BitConverter.ToString(refreshToken).Replace("-", ""));

                    if (secretClaim == null)
                    {
                        throw new SecurityException("Invalid refresh token");
                    }

                    // Next we ensure that the claim isn't expired
                    var expiryClaim = dataContext.SecurityUserClaims.FirstOrDefault(o => o.ClaimType == SqlServerConstants.RefreshExpiryClaimType && o.UserId == secretClaim.UserId);
                    if (expiryClaim == null || DateTimeOffset.Parse(expiryClaim.ClaimValue) < DateTime.Now)
                    {
                        throw new SecurityException("Token expired");
                    }

                    dataContext.sp_Authenticate(secretClaim.SecurityUser.UserName, secretClaim.SecurityUser.UserPassword, 3, ref userId);
                }

                using (var dataContext = new Data.ModelDataContext(s_configuration.ReadonlyConnectionString))
                {
                    var user         = dataContext.SecurityUsers.SingleOrDefault(u => u.UserId == userId);
                    var userIdentity = new SqlClaimsIdentity(user, true)
                    {
                        m_authenticationType = "Refresh"
                    };

                    // Is user allowed to login?
                    if (user.UserClass == UserClassKeys.HumanUser)
                    {
                        new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PermissionPolicyIdentifiers.Login, new GenericPrincipal(userIdentity, null)).Demand();
                    }
                    else if (user.UserClass == UserClassKeys.ApplicationUser)
                    {
                        new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PermissionPolicyIdentifiers.LoginAsService, new GenericPrincipal(userIdentity, null)).Demand();
                    }

                    return(userIdentity);
                }
            }
            catch (AuthenticationException)
            {
                // TODO: Audit this
                throw;
            }
            catch (SecurityException)
            {
                // TODO: Audit this
                throw;
            }
            catch (SqlException e)
            {
                switch (e.Number)
                {
                case 51900:
                    throw new AuthenticationException("Account is locked");

                case 51901:
                    throw new AuthenticationException("Invalid username/password");

                case 51902:
                    throw new AuthenticationException("User requires two-factor authentication");

                default:
                    throw e;
                }
            }
            catch (Exception e)
            {
                s_traceSource.TraceEvent(TraceEventType.Error, e.HResult, e.ToString());
                throw new Exception("Creating identity failed", e);
            }
        }