shiro記住我無效_原因及解決辦法


1、錯誤信息

Delegate RememberMeManager instance of type [" + rmm.getClass().getName() + "]

threw an exception during onSuccessfulLogin. RememberMe services will not be " + 

"performed for account [" + info + "].

 

2、原因

rememberMe記錄cookie時cookie的序列化出問題

可能是實體類無法序列化

或是cookie本身序列化出錯

 
         
protected void rememberMeSuccessfulLogin(AuthenticationToken token, AuthenticationInfo info, Subject subject) {
RememberMeManager rmm = getRememberMeManager();
if (rmm != null) {
try {
rmm.onSuccessfulLogin(subject, token, info);
} catch (Exception e) {
if (log.isWarnEnabled()) {
String msg = "Delegate RememberMeManager instance of type [" + rmm.getClass().getName() +
"] threw an exception during onSuccessfulLogin. RememberMe services will not be " +
"performed for account [" + info + "].";
log.warn(msg, e);
}
}
} else {
if (log.isTraceEnabled()) {
log.trace("This " + getClass().getName() + " instance does not have a " +
"[" + RememberMeManager.class.getName() + "] instance configured. RememberMe services " +
"will not be performed for account [" + info + "].");
}
}
}
 
        

如果shiro開啟了rememberMe,則在登錄成功后,會通過后置方法來到上面的代碼

可以看到執行 rmm.onSuccessfulLogin(subject, token, info) 下面有個catch方法

進入onSuccessfulLogin

 
         
public void onSuccessfulLogin(Subject subject, AuthenticationToken token, AuthenticationInfo info) {
//always clear any previous identity:
forgetIdentity(subject);//先執行forgetIdentity(subject)清除原來的cookie

//now save the new identity:
if (isRememberMe(token)) {
rememberIdentity(subject, token, info);//生成cookie並保存到瀏覽器
} else {
if (log.isDebugEnabled()) {
log.debug("AuthenticationToken did not indicate RememberMe is requested. " +
"RememberMe functionality will not be executed for corresponding account.");
}
}
}
 
        

進入rememberIdentity(subject, token, info)內部會來到如下:

 
         
protected void rememberSerializedIdentity(Subject subject, byte[] serialized) {

if (!WebUtils.isHttp(subject)) {
if (log.isDebugEnabled()) {
String msg = "Subject argument is not an HTTP-aware instance. This is required to obtain a servlet " +
"request and response in order to set the rememberMe cookie. Returning immediately and " +
"ignoring rememberMe operation.";
log.debug(msg);
}
return;
}


HttpServletRequest request = WebUtils.getHttpRequest(subject);
HttpServletResponse response = WebUtils.getHttpResponse(subject);

//base 64 encode it and store as a cookie:
String base64 = Base64.encodeToString(serialized);

Cookie template = getCookie(); //the class attribute is really a template for the outgoing cookies
Cookie cookie = new SimpleCookie(template);
cookie.setValue(base64);
cookie.saveTo(request, response);
}

最后幾行創建cookie實例,這中間就可能出現序列化或者cookie屬性缺少等問題

 

3、解決辦法

可能的解決辦法

確保subject.login()方法中傳入的實體類可以序列化

確保cookie參數完整(如必須有name屬性)

如果以上還是沒有解決,按上面的步驟調試進入內部查找


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM