Ejemplo n.º 1
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);
            }
        }
Ejemplo n.º 2
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);
            }
        }