最近新建的系統中使用了shiro,而shiro框架中包含登錄認證和鑒權的功能,因為我們系統要統一接入公司內部的單點登錄(isso)系統,所以通過isso的登錄用戶,需要在shiro中置為已認證,一下提供了兩種方案。
1、自建subject並綁定到當前線程(推薦)
import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.subject.SimplePrincipalCollection; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.ThreadContext; import org.apache.shiro.web.subject.WebSubject; /** * shiro對登錄用戶進行認證 * * @param request * @param response * @param loginUser */ private void shiroAuthenticationedUser(HttpServletRequest request, HttpServletResponse response, String loginUser) { // UserRealm是用戶認證和授權的具體實現類 PrincipalCollection principals = new SimplePrincipalCollection( loginUser, "FcocmpClientRealm"); WebSubject.Builder builder = new WebSubject.Builder(request, response); builder.principals(principals); // 已認證 builder.authenticated(true); // 保證shiro創建的sessionId與原有的sessionId不一致,統一取原有sessionId builder.sessionId(request.getSession().getId()); WebSubject subject = builder.buildWebSubject(); ThreadContext.bind(subject); }
2、使用isso用戶進行shiro登錄認證
import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; // loginUser是單點登錄用戶ID UsernamePasswordToken token = new UsernamePasswordToken(loginUser, "", true); Subject subject = org.apache.shiro.SecurityUtils.getSubject(); subject.login(token);
使用這個方案有可能會出現sessin異常問題:當切換登錄用戶時,執行subject.login(token)時,會用前一次用戶的sessionId取session,導致session獲取不到異常。
Caused by: org.apache.shiro.session.InvalidSessionException: java.lang.IllegalStateException: UT000010: Session not found g0gOlfwQXA1fHxriNq-JasOr at org.apache.shiro.web.session.HttpServletSession.getAttribute(HttpServletSession.java:148) [shiro-web-1.4.0.jar:1.4.0] at org.apache.shiro.web.session.HttpServletSession.getHost(HttpServletSession.java:98) [shiro-web-1.4.0.jar:1.4.0] at org.apache.shiro.session.ProxiedSession.getHost(ProxiedSession.java:93) [shiro-core-1.4.0.jar:1.4.0] at org.apache.shiro.subject.support.DefaultSubjectContext.resolveHost(DefaultSubjectContext.java:273) [shiro-core-1.4.0.jar:1.4.0] at org.apache.shiro.web.subject.support.DefaultWebSubjectContext.resolveHost(DefaultWebSubjectContext.java:51) [shiro-web-1.4.0.jar:1.4.0] at org.apache.shiro.web.mgt.DefaultWebSubjectFactory.createSubject(DefaultWebSubjectFactory.java:58) [shiro-web-1.4.0.jar:1.4.0] at org.apache.shiro.mgt.DefaultSecurityManager.doCreateSubject(DefaultSecurityManager.java:373) [shiro-core-1.4.0.jar:1.4.0] at org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:348) [shiro-core-1.4.0.jar:1.4.0] at org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:187) [shiro-core-1.4.0.jar:1.4.0] at org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:287) [shiro-core-1.4.0.jar:1.4.0] at org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:260) [shiro-core-1.4.0.jar:1.4.0]