/** * api登录接口,通过账号密码获取token */ @RequestMapping("/auth") public Object auth(@RequestParam("username") String username, @RequestParam("password") String password) { //封装请求账号密码为shiro可验证的token UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password.toCharArray()); //获取数据库中的账号密码,准备比对 User user = userMapper.getByAccount(username); String credentials = user.getPassword(); String salt = user.getSalt(); ByteSource credentialsSalt = new Md5Hash(salt); SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo( new ShiroUser(), credentials, credentialsSalt, ""); //校验用户账号密码 HashedCredentialsMatcher md5CredentialsMatcher = new HashedCredentialsMatcher(); md5CredentialsMatcher.setHashAlgorithmName(ShiroKit.hashAlgorithmName); md5CredentialsMatcher.setHashIterations(ShiroKit.hashIterations); boolean passwordTrueFlag = md5CredentialsMatcher.doCredentialsMatch( usernamePasswordToken, simpleAuthenticationInfo); if (passwordTrueFlag) { HashMap<String, Object> result = new HashMap<>(); result.put("token", JwtTokenUtil.generateToken(String.valueOf(user.getUserId()))); return result; } else { return new ErrorResponseData(500, "账号密码错误!"); } }
/** * Test backwards compatibility of unsalted credentials before * <a href="https://issues.apache.org/jira/browse/SHIRO-186">SHIRO-186</a> edits. */ @Test public void testBackwardsCompatibleUnsaltedAuthenticationInfo() { HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(Sha1Hash.ALGORITHM_NAME); //simulate an account with SHA-1 hashed password (no salt) final String username = "username"; final String password = "password"; final Object hashedPassword = new Sha1Hash(password).getBytes(); AuthenticationInfo account = new AuthenticationInfo() { public PrincipalCollection getPrincipals() { return new SimplePrincipalCollection(username, "realmName"); } public Object getCredentials() { return hashedPassword; } }; //simulate a username/password (plaintext) token created in response to a login attempt: AuthenticationToken token = new UsernamePasswordToken("username", "password"); //verify the hashed token matches what is in the account: assertTrue(matcher.doCredentialsMatch(token, account)); }
/** * Test new Shiro 1.1 functionality, where the salt is obtained from the stored account information, as it * should be. See <a href="https://issues.apache.org/jira/browse/SHIRO-186">SHIRO-186</a> */ @Test public void testSaltedAuthenticationInfo() { //use SHA-1 hashing in this test: HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(Sha1Hash.ALGORITHM_NAME); //simulate a user account with a SHA-1 hashed and salted password: ByteSource salt = new SecureRandomNumberGenerator().nextBytes(); Object hashedPassword = new Sha1Hash("password", salt); SimpleAuthenticationInfo account = new SimpleAuthenticationInfo("username", hashedPassword, salt, "realmName"); //simulate a username/password (plaintext) token created in response to a login attempt: AuthenticationToken token = new UsernamePasswordToken("username", "password"); //verify the hashed token matches what is in the account: assertTrue(matcher.doCredentialsMatch(token, account)); }
assertTrue(matcher.doCredentialsMatch(token, account));
public boolean doCredentialsMatch(String name, String password) { HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(this.hashAlgorithm); matcher.setHashIterations(this.hashIterations); AuthenticationToken token = new UsernamePasswordToken(name, password); AuthenticationInfo info = new SimpleAuthenticationInfo(this.name, ByteSource.Util.bytes(Base64.decode(this.password)), ByteSource.Util.bytes(Base64.decode(this.salt)), ""); return matcher.doCredentialsMatch(token, info); }
@Override public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { if (token instanceof UsernamePasswordToken) { return super.doCredentialsMatch(token, info); } else { return false; } }
final int iterations = 50000; AuthenticationToken authToken = ...; SaltedAuthenticationInfo saltedAuthInfo = ...; HashedCredentialsMatcher authenticator = new HashedCredentialsMatcher(Sha256Hash.ALGORITHM_NAME); authenticator.setHashIterations(iterations); final boolean successfulAuthentication = authenticator.doCredentialsMatch(authToken, saltedAuthInfo);
@Override public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) throws ExcessiveAttemptsException { String username = (String)token.getPrincipal(); AtomicInteger retryCount = passwordRetryCache.get(username); if(retryCount == null) { retryCount = new AtomicInteger(0); passwordRetryCache.put(username, retryCount); } if(retryCount.incrementAndGet() > retryMax) { throw new ExcessiveAttemptsException("您已连续错误达" + retryMax + "次!请10分钟后再试"); } boolean matches = super.doCredentialsMatch(token, info); if(matches) { passwordRetryCache.remove(username); }else { throw new IncorrectCredentialsException("密码错误,已错误" + retryCount.get() + "次,最多错误" + retryMax + "次"); } return true; }
@Override public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { String username = (String)token.getPrincipal(); //retry count + 1 AtomicInteger retryCount = passwordRetryCache.get(username); if(retryCount == null) { retryCount = new AtomicInteger(0); passwordRetryCache.put(username, retryCount); } if(retryCount.incrementAndGet() > 5) { //if retry count > 5 throw throw new ExcessiveAttemptsException(); } boolean matches = super.doCredentialsMatch(token, info); if(matches) { //clear retry count passwordRetryCache.remove(username); } return matches; } }
@Override public boolean doCredentialsMatch(AuthenticationToken authcToken, AuthenticationInfo info) { String username = (String) authcToken.getPrincipal(); //retry count + 1 AtomicInteger retryCount = passwordRetryCache.get(username); if(retryCount == null) { retryCount = new AtomicInteger(0); passwordRetryCache.put(username, retryCount); } if(retryCount.incrementAndGet() > 5) { //if retry count > 5 throw logger.warn("username: " + username + " tried to login more than 5 times in period"); throw new ExcessiveAttemptsException("用户名: " + username + " 密码连续输入错误超过5次,锁定半小时!"); } else { passwordRetryCache.put(username, retryCount); } boolean matches = super.doCredentialsMatch(authcToken, info); if(matches) { //clear retry data passwordRetryCache.remove(username); } return matches; }
@Override public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { String userName = (String)token.getPrincipal(); String key=this.getKey(userName); AtomicInteger retryCount; if(!redisTemplate.hasKey(key)) { retryCount =new AtomicInteger(0); }else{ retryCount = (AtomicInteger) redisTemplate.opsForValue().get(key); } log.info("userName:{},retryCount:{}",userName,retryCount); //retry count + 1 //大于等于最大次数 if(retryCount.incrementAndGet() >= this.retryMaxCount) { throw new ExcessiveAttemptsException("超过最大重试次数,最大值:"+this.retryMaxCount); } boolean matches = super.doCredentialsMatch(token, info); if(matches) { redisTemplate.delete(key); }else{ //默认设置为1天 redisTemplate.opsForValue().set(key,retryCount); redisTemplate.expire(key,1,TimeUnit.HOURS); log.info("userName:{},retryCount:{}",userName,retryCount); } return matches; }
@Override public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { String username = (String) token.getPrincipal(); // retry count + 1 AtomicInteger retryCount = passwordRetryCache.get(username); if (retryCount == null) { retryCount = new AtomicInteger(0); passwordRetryCache.put(username, retryCount); } if (retryCount.incrementAndGet() > 5) { // if retry count > 5 throw throw new ExcessiveAttemptsException("用户名: " + username + " 密码连续输入错误超过5次,锁定半小时!"); } else { passwordRetryCache.put(username, retryCount); } boolean matches = super.doCredentialsMatch(token, info); if (matches) { // clear retry count passwordRetryCache.remove(username); } return matches; } }
boolean matches = super.doCredentialsMatch(token, info); if (matches) {
matches = super.doCredentialsMatch(token, info); } else if (token.getLoginType().equals(MuitiLoginToken.TOKEN_MODE)) { SimpleCredentialsMatcher simpleMatcher = new SimpleCredentialsMatcher();
.doCredentialsMatch( PluginShiroAuthToken.of( token ), info );