Example #1
0
        /// <summary>
        /// Authenticate the user
        /// </summary>
        public IPrincipal Authenticate(string userName, string password)
        {
            var evt = new AuthenticatingEventArgs(userName);

            this.Authenticating?.Invoke(this, evt);
            if (evt.Cancel)
            {
                throw new SecurityException("Authentication cancelled");
            }

            try
            {
                var principal = SqlClaimsIdentity.Create(userName, password).CreateClaimsPrincipal();
                this.Authenticated?.Invoke(this, new AuthenticatedEventArgs(userName, principal, true));
                return(principal);
            }
            catch (SecurityException e)
            {
                this.m_traceSource.TraceEvent(TraceEventType.Verbose, e.HResult, "Invalid credentials : {0}/{1}", userName, password);

                this.m_traceSource.TraceEvent(TraceEventType.Error, e.HResult, e.ToString());
                this.Authenticated?.Invoke(this, new AuthenticatedEventArgs(userName, null, false));
                throw;
            }
        }
Example #2
0
        /// <summary>
        /// Create a basic user
        /// </summary>
        public IIdentity CreateIdentity(string userName, string password, IPrincipal authContext)
        {
            if (String.IsNullOrEmpty(userName))
            {
                throw new ArgumentNullException(nameof(userName));
            }
            else if (String.IsNullOrEmpty(password))
            {
                throw new ArgumentNullException(nameof(password));
            }
            else if (authContext == null)
            {
                throw new ArgumentNullException(nameof(authContext));
            }

            this.m_traceSource.TraceInformation("Creating identity {0} ({1})", userName, authContext);

            try
            {
                using (var dataContext = new ModelDataContext(this.m_configuration.ReadWriteConnectionString))
                {
                    var hashingService = ApplicationContext.Current.GetService <IPasswordHashingService>();
                    var pdpService     = ApplicationContext.Current.GetService <IPolicyDecisionService>();

                    // Demand create identity
                    new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PermissionPolicyIdentifiers.CreateIdentity, authContext).Demand();

                    // Does this principal have the ability to
                    Data.SecurityUser newIdentityUser = new Data.SecurityUser()
                    {
                        UserId        = Guid.NewGuid(),
                        UserName      = userName,
                        UserPassword  = hashingService.EncodePassword(password),
                        SecurityStamp = Guid.NewGuid().ToString(),
                        UserClass     = UserClassKeys.HumanUser
                    };
                    if (authContext != null)
                    {
                        newIdentityUser.CreatedByEntity = dataContext.SecurityUsers.Single(u => u.UserName == authContext.Identity.Name);
                    }

                    dataContext.SecurityUsers.InsertOnSubmit(newIdentityUser);
                    dataContext.SubmitChanges();

                    return(SqlClaimsIdentity.Create(newIdentityUser));
                }
            }
            catch (Exception e)
            {
                this.m_traceSource.TraceEvent(TraceEventType.Error, e.HResult, e.ToString());
                throw;
            }
        }
Example #3
0
        /// <summary>
        /// Authenticate using a refresh token
        /// </summary>
        public IPrincipal Authenticate(byte[] refreshToken)
        {
            if (refreshToken == null)
            {
                throw new ArgumentNullException(nameof(refreshToken));
            }
            else if (refreshToken.Length != 32)
            {
                throw new ArgumentOutOfRangeException(nameof(refreshToken), "Invalid refresh token");
            }


            string trokenName = BitConverter.ToString(refreshToken).Replace("-", "");
            var    evt        = new AuthenticatingEventArgs(trokenName);

            this.Authenticating?.Invoke(this, evt);
            if (evt.Cancel)
            {
                throw new SecurityException("Authentication cancelled");
            }

            try
            {
                var principal = SqlClaimsIdentity.Create(refreshToken).CreateClaimsPrincipal();
                this.Authenticated?.Invoke(this, new AuthenticatedEventArgs(trokenName, principal, true));
                return(principal);
            }
            catch (SecurityException e)
            {
                this.m_traceSource.TraceEvent(TraceEventType.Verbose, e.HResult, "Invalid credentials : {0}", refreshToken);

                this.m_traceSource.TraceEvent(TraceEventType.Error, e.HResult, e.ToString());
                this.Authenticated?.Invoke(this, new AuthenticatedEventArgs(trokenName, null, false));
                throw;
            }
        }
Example #4
0
        /// <summary>
        /// Authenticate the user using a TwoFactorAuthentication secret
        /// </summary>
        public IPrincipal Authenticate(string userName, string password, string tfaSecret)
        {
            // First, let's verify the TFA
            if (String.IsNullOrEmpty(userName))
            {
                throw new ArgumentNullException(nameof(userName));
            }
            else if (String.IsNullOrEmpty(tfaSecret))
            {
                throw new ArgumentNullException(nameof(tfaSecret));
            }

            // Authentication event args
            var evt = new AuthenticatingEventArgs(userName);

            this.Authenticating?.Invoke(this, evt);
            if (evt.Cancel)
            {
                throw new SecurityException("Authentication cancelled");
            }

            // Password hasher
            var hashingService = ApplicationContext.Current.GetService <IPasswordHashingService>();

            tfaSecret = hashingService.EncodePassword(tfaSecret);

            // Try to authenticate
            try
            {
                using (var dataContext = new ModelDataContext(this.m_configuration.ReadWriteConnectionString))
                {
                    var user = dataContext.SecurityUsers.FirstOrDefault(o => o.UserName == userName);
                    if (user == null)
                    {
                        throw new KeyNotFoundException(userName);
                    }
                    SecurityUserClaim tfaClaim   = dataContext.SecurityUserClaims.FirstOrDefault(o => o.UserId == user.Id && o.ClaimType == OpenIzClaimTypes.OpenIZTfaSecretClaim),
                                      tfaExpiry  = dataContext.SecurityUserClaims.FirstOrDefault(o => o.UserId == user.Id && o.ClaimType == OpenIzClaimTypes.OpenIZTfaSecretExpiry),
                                      noPassword = dataContext.SecurityUserClaims.FirstOrDefault(o => o.UserId == user.Id && o.ClaimType == OpenIzClaimTypes.OpenIZPasswordlessAuth);

                    if (tfaClaim == null || tfaExpiry == null)
                    {
                        throw new InvalidOperationException("Cannot find appropriate claims for TFA");
                    }

                    // Expiry check
                    ClaimsPrincipal retVal     = null;
                    DateTime        expiryDate = DateTime.Parse(tfaExpiry.ClaimValue);
                    if (expiryDate < DateTime.Now)
                    {
                        throw new SecurityException("TFA secret expired");
                    }
                    else if (String.IsNullOrEmpty(password) &&
                             Boolean.Parse(noPassword?.ClaimValue ?? "false") &&
                             tfaSecret == tfaClaim.ClaimValue) // Last known password hash sent as password, this is a password reset token - It will be set to expire ASAP
                    {
                        retVal = SqlClaimsIdentity.Create(user, true, "Tfa+LastPasswordHash").CreateClaimsPrincipal();
                        (retVal.Identity as ClaimsIdentity).AddClaim(new Claim(OpenIzClaimTypes.OpenIzGrantedPolicyClaim, PermissionPolicyIdentifiers.ChangePassword));
                        (retVal.Identity as ClaimsIdentity).RemoveClaim(retVal.FindFirst(ClaimTypes.Expiration));
                        // TODO: Add to configuration
                        (retVal.Identity as ClaimsIdentity).AddClaim(new Claim(ClaimTypes.Expiration, DateTime.Now.AddMinutes(5).ToString("o")));
                    }
                    else if (!String.IsNullOrEmpty(password))
                    {
                        retVal = this.Authenticate(userName, password) as ClaimsPrincipal;
                    }
                    else
                    {
                        throw new PolicyViolationException(PermissionPolicyIdentifiers.Login, PolicyDecisionOutcomeType.Deny);
                    }

                    // Now we want to fire authenticated
                    this.Authenticated?.Invoke(this, new AuthenticatedEventArgs(userName, retVal, true));
                    return(retVal);
                }
            }
            catch (Exception e)
            {
                this.m_traceSource.TraceEvent(TraceEventType.Verbose, e.HResult, "Invalid credentials : {0}/{1}", userName, password);
                this.m_traceSource.TraceEvent(TraceEventType.Error, e.HResult, e.ToString());
                this.Authenticated?.Invoke(this, new AuthenticatedEventArgs(userName, null, false));
                throw;
            }
        }
Example #5
0
 /// <summary>
 /// Gets an un-authenticated identity
 /// </summary>
 public IIdentity GetIdentity(string userName)
 {
     return(SqlClaimsIdentity.Create(userName));
 }