Spring Boot +Shiro 驗證碼Filter和限制密碼錯誤次數
阿新 • • 發佈:2019-01-02
驗證碼校驗
CustomFormAuthenticationFilter 將我們自己實現的Filter,放到ShiroFilterFactoryBean中。
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
Map<String, Filter> filters = shiroFilterFactoryBean.getFilters();//獲取filters
filters.put("authc", new CustomFormAuthenticationFilter());//將自定義 的FormAuthenticationFilter注入shiroFilter中
CustomFormAuthenticationFilter.java
public class CustomFormAuthenticationFilter extends FormAuthenticationFilter {
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
// 在這裡進行驗證碼的校驗
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpSession session = httpServletRequest.getSession();
// 取出驗證碼
String validateCode = (String) session.getAttribute("validateCode");
// 取出頁面的驗證碼
// 輸入的驗證和session中的驗證進行對比
String randomcode = httpServletRequest.getParameter("randomcode");
if (randomcode != null && validateCode != null && !randomcode.equals(validateCode)) {
// 如果校驗失敗,將驗證碼錯誤失敗資訊,通過shiroLoginFailure設定到request中
httpServletRequest.setAttribute("shiroLoginFailure", "kaptchaValidateFailed");//自定義登入異常
// 拒絕訪問,不再校驗賬號和密碼
return true;
}
return super.onAccessDenied(request, response);
}
}
密碼錯誤次數限制登入
RetryLimitHashedCredentialsMatcher 繼承HashedCredentialsMatcher
在我們實現的MyShiroRealm密碼匹配器中使用我們自己寫的RetryLimitHashedCredentialsMatcher
重點內容
/**
* 身份認證realm;
* (這個需要自己寫,賬號密碼校驗;許可權等)
* @return
*/
@Bean
public MyShiroRealm myShiroRealm(){
MyShiroRealm myShiroRealm = new MyShiroRealm();
myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());;
return myShiroRealm;
}
/**
* 憑證匹配器
* (由於我們的密碼校驗交給Shiro的SimpleAuthenticationInfo進行處理了
* 所以我們需要修改下doGetAuthenticationInfo中的程式碼;
* )
* @return
*/
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher(){
// HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
HashedCredentialsMatcher hashedCredentialsMatcher = new RetryLimitHashedCredentialsMatcher(ehCacheManager());
hashedCredentialsMatcher.setHashAlgorithmName("md5");//雜湊演算法:這裡使用MD5演算法;
hashedCredentialsMatcher.setHashIterations(2);//雜湊的次數,比如雜湊兩次,相當於 md5(md5(""));
return hashedCredentialsMatcher;
}
public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher {
private Cache<String, AtomicInteger> passwordRetryCache;
public RetryLimitHashedCredentialsMatcher(CacheManager cacheManager) {
passwordRetryCache = cacheManager.getCache("passwordRetryCache");
}
@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;
}
}