/// <summary> /// Creates a principal based on username and password /// </summary> internal static AdoClaimsIdentity Create(String userName, String password) { try { if (userName == AuthenticationContext.AnonymousPrincipal.Identity.Name || userName == AuthenticationContext.SystemPrincipal.Identity.Name) { throw new PolicyViolationException(new GenericPrincipal(new GenericIdentity(userName), new String[0]), PermissionPolicyIdentifiers.Login, PolicyGrantType.Deny); } Guid?userId = Guid.Empty; using (var dataContext = s_configuration.Provider.GetWriteConnection()) { dataContext.Open(); // Attempt to get a user var hashingService = ApplicationServiceContext.Current.GetService <IPasswordHashingService>(); var passwordHash = hashingService.ComputeHash(password); var fnResult = dataContext.FirstOrDefault <CompositeResult <DbSecurityUser, FunctionErrorCode> >("auth_usr", userName, passwordHash, s_securityConfiguration?.GetSecurityPolicy(SecurityPolicyIdentification.MaxInvalidLogins, 5) ?? 5); var user = fnResult.Object1; if (!String.IsNullOrEmpty(fnResult.Object2.ErrorCode)) { if (fnResult.Object2.ErrorCode.Contains("AUTH_LCK:")) { UpdateCache(user, dataContext); } throw new AuthenticationException(fnResult.Object2.ErrorCode); } var roles = dataContext.Query <DbSecurityRole>(dataContext.CreateSqlStatement <DbSecurityRole>().SelectFrom() .InnerJoin <DbSecurityUserRole>(o => o.Key, o => o.RoleKey) .Where <DbSecurityUserRole>(o => o.UserKey == user.Key)); var userIdentity = new AdoClaimsIdentity(user, roles, 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(); } // add the security user to the cache before exiting UpdateCache(user, dataContext); return(userIdentity); } } catch (AuthenticationException e) { // TODO: Audit this if (e.Message.Contains("AUTH_INV:") || e.Message.Contains("AUTH_LCK:") || e.Message.Contains("AUTH_TFA:")) { throw new AuthenticationException(e.Message.Substring(0, e.Message.IndexOf(":")), e); } else { throw; } } catch (SecurityException) { // TODO: Audit this throw; } catch (DbException e) { s_traceSource.TraceEvent(EventLevel.Error, "Database Error Creating Identity: {0}", e); throw new AuthenticationException(e.Message, e); } catch (Exception e) { s_traceSource.TraceEvent(EventLevel.Error, e.ToString()); throw new Exception("Creating identity failed", e); } }
/// <summary> /// Create an authorization context /// </summary> public IClaimsPrincipal CreateClaimsPrincipal(IEnumerable <IClaimsIdentity> otherIdentities = null) { if (!this.IsAuthenticated) { throw new SecurityException("Principal is not authenticated"); } try { // System claims List <IClaim> claims = new List <IClaim>( ) { new SanteDBClaim(SanteDBClaimTypes.AuthenticationMethod, this.m_authenticationType ?? "LOCAL"), new SanteDBClaim(SanteDBClaimTypes.Sid, this.m_securityUser.Key.ToString()), new SanteDBClaim(SanteDBClaimTypes.NameIdentifier, this.m_securityUser.Key.ToString()), new SanteDBClaim(SanteDBClaimTypes.Actor, this.m_securityUser.UserClass.ToString()), }; if (!this.Claims.Any(o => o.Type == SanteDBClaimTypes.Name)) { claims.Add(new SanteDBClaim(SanteDBClaimTypes.Name, this.m_securityUser.UserName)); } if (!this.Claims.Any(o => o.Type == SanteDBClaimTypes.DefaultRoleClaimType)) { claims.AddRange(this.m_roles.Select(r => new SanteDBClaim(SanteDBClaimTypes.DefaultRoleClaimType, r.Name))); } if (this.m_securityUser.PasswordExpiration.HasValue && this.m_securityUser.PasswordExpiration < DateTime.Now) { claims.Add(new SanteDBClaim(SanteDBClaimTypes.PurposeOfUse, PurposeOfUseKeys.SecurityAdmin.ToString())); claims.Add(new SanteDBClaim(SanteDBClaimTypes.SanteDBScopeClaim, PermissionPolicyIdentifiers.LoginPasswordOnly)); claims.Add(new SanteDBClaim(SanteDBClaimTypes.SanteDBScopeClaim, PermissionPolicyIdentifiers.ReadMetadata)); } if (this.m_securityUser.Email != null) { claims.Add(new SanteDBClaim(SanteDBClaimTypes.Email, this.m_securityUser.Email)); } if (this.m_securityUser.PhoneNumber != null) { claims.Add(new SanteDBClaim(SanteDBClaimTypes.Telephone, this.m_securityUser.PhoneNumber)); } this.AddClaims(claims); var identities = new IClaimsIdentity[] { this }; if (otherIdentities != null) { identities = identities.Union(otherIdentities).ToArray(); } // TODO: Demographic data for the user var retVal = new SanteDBClaimsPrincipal( identities ); s_traceSource.TraceInfo("Created security principal from identity {0} > {1}", this, AdoClaimsIdentity.PrincipalToString(retVal)); return(retVal); } catch (Exception e) { s_traceSource.TraceEvent(EventLevel.Error, e.ToString()); throw new Exception("Creating principal from identity failed", e); } }