public virtual IHttpActionResult RequestRefresh([FromBody] RefreshParams rp)
        {
            return(ExecuteValidatedAction(() =>
            {
                // manually validating, as api is no longer wired up...
                ValidatorHelpers.ValidateAndThrow(rp, new RefreshParamsValidator());

                // validate AuthClient and RefreshToken
                JwtConfig config = new JwtConfig(true, RequestLeftPart);
                AuthClient client = ValidateClient(rp);
                AuthToken rt = AuthService.RetrieveToken(rp.AuthUserId, rp.AuthClientId, rp.TokenIdentifier);

                AddNoCacheHeader();

                if (client == null || rt == null || rt.AuthClientId != client.Id ||
                    !JsonWebToken.GrantNewAccess(config, rt.Token))
                {
                    return ImATeapot();
                }

                // get user
                AuthUser user = AuthService.GetByIdForLogin(rt.AuthUserId);
                if (user == null)
                {
                    return ImATeapot();
                }

                CheckSetRoleManager(user);                                             // make sure state is set in RoleManager
                ILoginResultDto loginResult = CreateTokenResult(user, client, config); // create new tokens, return result
                return loginResult != null ? (IHttpActionResult)Ok(loginResult) : ImATeapot();
            }));
        }
示例#2
0
        /// <summary>
        ///      Generates a reset link and sets to auth user's designated email. For use on initial
        ///      creation of new users.
        /// </summary>
        /// <param name="user"> </param>
        /// <param name="email"></param>
        public void SendNewUserResetEmail(AuthUser user, string email)
        {
            string msgText = "A new account has been created for " + user.Username +
                             ". Please use the following link within 24 hours to set up a password:"******"New Account Created", msgText);
        }
        public virtual IHttpActionResult ResetPassword([FromBody] ResetPasswordParams rpp)
        {
            return(ExecuteValidatedAction(() =>
            {
                ValidatorHelpers.ValidateAndThrow(rpp, new ResetPasswordParamsValidator());

                // validate client
                AuthClient client = ValidateClient(rpp);
                if (client == null)
                {
                    return ImATeapot();
                }

                // validate user
                AuthUser user = AuthService.ValidateReset(rpp.AuthUserId, rpp.ResetKey);
                if (user == null)
                {
                    return BadRequest();
                }

                // change password
                AuthService.UpdatePassword(user, rpp.Password);
                CheckSetRoleManager(user);                                // make sure state is set in RoleManager
                ILoginResultDto result = CreateTokenResult(user, client); // return token
                AuthService.MarkResetInvalid(rpp.AuthUserId);
                return result != null ? (IHttpActionResult)Ok(result) : ImATeapot();
            }));
        }
示例#4
0
        /// <summary>
        ///      Creates a new AuthUser, given a username and password. Returns the new AuthUser's Id.
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <param name="userRoleId"></param>
        /// <returns>Returns the Id of the created AuthUser.</returns>
        public int Create(string username, string password, int userRoleId)
        {
            AuthUser au = GenerateAuthUser(username, false, password, userRoleId);

            Context.AuthUsers.Add(au);
            Context.SaveChanges();
            return(au.Id);
        }
        /// <summary>
        ///      This method can be overridden to return specific info about whatever entity is being
        ///      used for authentication, so long as the return type implements the ILoginResultDto interface.
        /// </summary>
        /// <param name="authUser"></param>
        /// <param name="client"></param>
        /// <param name="config"></param>
        /// <returns></returns>
        protected virtual ILoginResultDto CreateTokenResult(AuthUser authUser, AuthClient client, JwtConfig config)
        {
            LoginResult lr = GetBaseLoginResult(authUser, client, config);

            return(new DefaultLoginResult {
                LoginResult = lr
            });
        }
示例#6
0
 /// <summary>
 ///     Updates an AuthUser.
 /// </summary>
 /// <param name="authUser"></param>
 /// <returns>Returns the updated AuthUser.</returns>
 public AuthUser Update(AuthUser authUser)
 {
     ThrowIfNull(authUser);
     ValidateAndThrow(authUser, _authValidator);
     Context.SetEntityState(authUser, EntityState.Modified);
     Context.SaveChanges();
     return(authUser);
 }
示例#7
0
        private static string CreateResetLink(AuthUser user, string resetKey)
        {
            var adminSite     = AppSettings.GetAdminSite();
            var resetEndpoint = AppSettings.GetResetEndpoint();
            var href          = $"{adminSite}{resetEndpoint}?resetKey={resetKey}&userId={user.Id}";

            return(GenerateLink(href, "Reset Password"));
        }
示例#8
0
        private void SendResetEmail(AuthUser user, string email, string title, string msgText)
        {
            string resetKey = HttpServerUtility.UrlTokenEncode(user.ResetKey);
            string from     = AppSettings.GetDefaultEmailFrom();
            string link     = CreateResetLink(user, resetKey);
            string body     = $"{msgText}<br />{link}";

            Email.SendEmail(from, email, title, body);
        }
示例#9
0
        /// <summary>
        ///     Accepts reset key. Used during forgot password.
        /// </summary>
        /// <param name="userId">  </param>
        /// <param name="resetKey"></param>
        /// <returns>Returns a validated AuthUser, or null if validation failed.</returns>
        public AuthUser ValidateReset(int userId, string resetKey)
        {
            AuthUser user = GetByIdForLogin(userId);

            if (user == null)
            {
                return(null);
            }
            byte[] keyBytes = HttpServerUtility.UrlTokenDecode(resetKey);
            return(IsValidResetKey(user, keyBytes) ? user : null);
        }
示例#10
0
        /// <summary>
        ///      Sends an invite email without a reset link.
        /// </summary>
        /// <param name="user"> </param>
        /// <param name="email"></param>
        public void SendNewUserInitEmail(AuthUser user, string email)
        {
            string msgText = $"A new account has been created for {user.Username}. " +
                             "You may use use this to sign in:";
            string       from  = AppSettings.GetDefaultEmailFrom();
            string       link  = CreateDefaultAdminSiteLink();
            const string title = "New Account Created";
            string       body  = $"{msgText}<br />{link}";

            Email.SendEmail(from, email, title, body);
        }
示例#11
0
        private static IDictionary <string, string[]> CreateJwtPayload(AuthUser user, AuthClient client)
        {
            var payload = new Dictionary <string, string[]>
            {
                [OwinKeys.AuthUserId]   = new[] { user.Id.ToString() },
                [OwinKeys.AuthUsername] = new[] { user.Username },
                [OwinKeys.AuthClientId] = new[] { client.Id.ToString() },
                [OwinKeys.UserRoleId]   = new[] { user.RoleId.ToString() }
            };

            return(payload);
        }
示例#12
0
        public async Task <ActionResult <Model.AuthUser> > PostAuthUser(Model.AuthUser insert)
        {
            Models.AuthUser input = _mapper.Map <Models.AuthUser>(insert);

            _context.AuthUser.Add(input);
            await _context.SaveChangesAsync();


            var result = await _context.AuthUser.FindAsync(input.Id);

            return(_mapper.Map <Model.AuthUser>(result));

            //return CreatedAtAction("Get", new { id = authUser.Id }, authUser);
        }
示例#13
0
        /// <summary>
        ///      Updates a user's password.
        /// </summary>
        /// <param name="user"></param>
        /// <param name="password"></param>
        /// <returns>Returns true unless an error occurs.</returns>
        public bool UpdatePassword(AuthUser user, string password)
        {
            ThrowIfNull(user);
            if (!user.IsEditable)
            {
                throw new ValidationException("This is a protected user and cannot be edited.");
            }
            ValidatePasswordStrength(password);
            var sh = new SaltedHashGenerator(password);

            user.Password = sh.SaltedHash;
            user.Salt     = sh.Salt;
            Context.SetEntityState(user, EntityState.Modified);
            Context.SaveChanges();
            return(true);
        }
示例#14
0
        /// <summary>
        ///     Creates a basic login result.
        ///     Adds user role claims to Jwt payload
        ///     NOTE: If you duplicate a key in the additionalPayload, this will error.
        /// </summary>
        /// <param name="authUser"></param>
        /// <param name="client"></param>
        /// <param name="config"></param>
        /// <param name="additionalPayload"></param>
        /// <returns></returns>
        protected LoginResult GetBaseLoginResult(AuthUser authUser, AuthClient client, JwtConfig config, IDictionary <string, string> additionalPayload = null)
        {
            config.RefreshMinutes = client.RefreshTokenMinutes; // MUST set refresh minutes by client
            var now = DateTime.UtcNow;
            IDictionary <string, string[]> payload = CreateJwtPayload(authUser, client);

            if (additionalPayload != null)
            {
                foreach (var kv in additionalPayload)
                {
                    payload.Add(kv.Key, new[] { kv.Value });
                }
            }
            // add ossied time for easier parsing
            payload.Add(OwinKeys.Ticks, new[] { now.Ticks.ToString() });

            // add claims
            bool hasClaims  = (authUser.UserRole?.UserRoleClaims != null);
            var  claimFlags = new Dictionary <int, int>();

            if (hasClaims)
            {
                foreach (var cgroup in authUser.UserRole.UserRoleClaims.GroupBy(cv => cv.ClaimTypeId))
                {
                    int claimValues = cgroup.Aggregate(0, (v, urc) => v | urc.ClaimValueId); // | them together
                    claimFlags.Add(cgroup.Key, claimValues);
                    payload[ClaimsHelper.SetTypePrefix(cgroup.Key)] = new [] { claimValues.ToString() };
                }
            }

            string accessToken  = JsonWebToken.CreateAccessToken(config, now, payload);
            string refreshToken = JsonWebToken.CreateRefreshToken(config, now, payload);
            string csrfToken    = CsrfToken.Create(accessToken);
            Guid   refreshGuid  = AuthService.CreateToken(authUser.Id, client.Id, now, config.RefreshMinutes, refreshToken);

            return(new LoginResult
            {
                AuthUserId = authUser.Id,
                ClaimFlags = claimFlags,
                IssuedUtc = now,
                ExpiresUtc = now.AddMinutes(config.AccessMinutes),
                RefreshTokenIdentifier = refreshGuid.ToString(),
                Jwt = accessToken,
                CsrfToken = csrfToken
            });
        }
示例#15
0
        public virtual IHttpActionResult GrantAdminDomainEmailAccess([FromBody] DomainEmailPasswordParams depp)
        {
            return(ExecuteValidatedAction(() =>
            {
                ValidatorHelpers.ValidateAndThrow(depp, new DomainEmailPasswordParamsValidator());

                AuthClient client = ValidateClient(depp);
                if (client == null)
                {
                    return ImATeapot();
                }

                AuthUser au = AuthService.ValidateDomainEmailLogin(depp.ResetKey);
                if (au == null)
                {
                    return ImATeapot();
                }

                CheckSetRoleManager(au);
                ILoginResultDto result = CreateTokenResult(au, client); // return token
                return result != null ? (IHttpActionResult)Ok(result) : ImATeapot();
            }));
        }
示例#16
0
        /// <summary>
        ///     Overload that accepts userId instead of username. Useful when validating user before
        ///     updating a password.
        /// </summary>
        /// <param name="userId">  </param>
        /// <param name="password"></param>
        /// <returns>Returns a validated AuthUser, or null if validation failed.</returns>
        public AuthUser ValidateLogin(int userId, string password)
        {
            AuthUser user = GetByIdForLogin(userId);

            return((AuthUser)CheckVerifiableByPassword(user, password));
        }
示例#17
0
 /// <summary>
 ///     Validates an AuthUser.
 /// </summary>
 /// <param name="user"></param>
 public void ValidateAndThrow(AuthUser user)
 {
     ValidateAndThrow(user, _authValidator);
 }
示例#18
0
        /// <summary>
        ///      Generates a reset link and sends to auth user's designated email. For use when users
        ///      forget their passwords.
        /// </summary>
        /// <param name="user"> </param>
        /// <param name="email"></param>
        public void SendForgotPasswordEmail(AuthUser user, string email)
        {
            const string msgText = "Please use the following link to reset your password:"******"Reset Password", msgText);
        }
示例#19
0
 /// <summary>
 ///      Checks username for uniqueness. This can be chained in the Must extension overload
 ///      for Fluent Validation, which accepts the entity itself as the first parameter if you
 ///      need to use another field in your logic.
 /// </summary>
 /// <param name="user">    </param>
 /// <param name="username"></param>
 /// <returns></returns>
 public bool IsUniqueUsername(AuthUser user, string username)
 {
     return(!Context.AuthUsers.Any(au => au.Username == username && au.Id != user.Id));
 }
示例#20
0
 private bool IsValidResetKey(AuthUser user, byte[] keyBytes)
 {
     return(keyBytes != null &&
            keyBytes.SequenceEqual(user.ResetKey) &&
            user.ResetKeyExpirationUtc >= DateTime.UtcNow);
 }
示例#21
0
        protected ILoginResultDto CreateTokenResult(AuthUser user, AuthClient client)
        {
            JwtConfig config = new JwtConfig(true, RequestLeftPart);

            return(CreateTokenResult(user, client, config));
        }
示例#22
0
 /// <summary>
 ///      Sets a new reset key for a user, good for 15 minutes by default.
 /// </summary>
 /// <param name="user">        </param>
 /// <param name="resetMinutes"></param>
 public void SetResetKey(AuthUser user, int resetMinutes = 15)
 {
     user.ResetKey = Encryption.GetSalt();
     user.ResetKeyExpirationUtc = DateTime.UtcNow.AddMinutes(resetMinutes);
     Update(user);
 }
示例#23
0
 private void CheckSetRoleManager(AuthUser user)
 {
     RoleManager.CheckSetUserTime(user.Id);
     RoleManager.CheckSetRoleTime(user.RoleId);
 }