這篇文章主要講解了“shiro集成jwt怎么禁用session”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“shiro集成jwt怎么禁用session”吧!
我們提供的服務(wù)有:成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、外貿(mào)營銷網(wǎng)站建設(shè)、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、康平ssl等。為成百上千家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的康平網(wǎng)站制作公司
shiro 集成 jwt 需要禁用 session, 服務(wù)器就不用維護(hù)用戶的狀態(tài), 做到無狀態(tài)調(diào)用
org.apache.shiro shiro-spring-boot-web-starter 1.5.3
com.auth0 java-jwt 3.10.3
1. 定義一個(gè) JwtToken, 用來封裝 username 和 jsonWebToken
package com.codingos.shirojwt.shiro; import org.apache.shiro.authc.AuthenticationToken; public class JwtToken implements AuthenticationToken{ private static final long serialVersionUID = 5467074955086481181L; private String username; private String jsonWebToken; public JwtToken(String username, String jsonWebToken) { this.username = username; this.jsonWebToken = jsonWebToken; } @Override public Object getPrincipal() { return username; } @Override public Object getCredentials() { return jsonWebToken; } }
2. 自定義一個(gè) Filter 用來過濾所有請求, 交給realm進(jìn)行驗(yàn)證
package com.codingos.shirojwt.shiro; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.web.filter.AccessControlFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.auth0.jwt.JWT; import com.auth0.jwt.interfaces.DecodedJWT; import com.codingos.shirojwt.common.CommonUtils; public class CustomFilter extends AccessControlFilter{ private final Logger logger = LoggerFactory.getLogger(getClass()); @Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception { return false; } @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { if(logger.isDebugEnabled()) { logger.debug("訪問的URI: {}", ((HttpServletRequest) request).getRequestURI()); } String jsonWebToken = CommonUtils.getJsonWebToken((HttpServletRequest) request); String username = ""; if (StringUtils.isBlank(jsonWebToken)) { jsonWebToken = ""; } else { // 解碼 jwt DecodedJWT decodeJwt = JWT.decode(jsonWebToken); username = decodeJwt.getClaim("username").asString(); } JwtToken token = new JwtToken(username, jsonWebToken); try { // 交給自定義realm進(jìn)行jwt驗(yàn)證和對應(yīng)角色,權(quán)限的查詢 getSubject(request, response).login(token); } catch (AuthenticationException e) { request.setAttribute("msg", "認(rèn)證失敗"); // 轉(zhuǎn)發(fā)給指定的 controller, 進(jìn)行統(tǒng)一異常處理 ((HttpServletRequest)request).getRequestDispatcher("/exception").forward(request, response); return false; } return true; } }
3. 創(chuàng)建自定義realm, 用來驗(yàn)證 jwt , role, permission
package com.codingos.shirojwt.shiro; import java.util.Set; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import com.auth0.jwt.JWT; import com.auth0.jwt.JWTVerifier; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.exceptions.JWTVerificationException; import com.codingos.shirojwt.constant.Constant; import com.codingos.shirojwt.service.ShiroService; public class CustomRealm extends AuthorizingRealm { private final Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private ShiroService shiroService; public CustomRealm() { } @Override public boolean supports(AuthenticationToken token) { // 僅支持 JwtToken return token instanceof JwtToken; } @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { // 獲取用戶名, 用戶唯一標(biāo)識 String username = (String) principals.getPrimaryPrincipal(); SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); SetpermissionSet = shiroService.listPermissions(username); permissionSet.add("perm-1"); // 造數(shù)據(jù), 假裝是從數(shù)據(jù)庫查出來的 permissionSet.add("perm-2"); simpleAuthorizationInfo.setStringPermissions(permissionSet); Set roleSet = shiroService.listRoles(username); roleSet.add("role-1"); // 造數(shù)據(jù), 假裝是從數(shù)據(jù)庫查出來的 roleSet.add("role-2"); simpleAuthorizationInfo.setRoles(roleSet); return simpleAuthorizationInfo; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String username = (String) token.getPrincipal(); String jsonWebToken = (String) token.getCredentials(); Algorithm algorithm = Algorithm.HMAC256(Constant.JWT_SECRET); JWTVerifier verifier = JWT.require(algorithm).build(); try { verifier.verify(jsonWebToken); if(logger.isDebugEnabled()) { logger.debug("********************* 驗(yàn)證通過 ***********************"); } } catch (JWTVerificationException e) { if(logger.isDebugEnabled()) { logger.debug("********************* 驗(yàn)證不通過 **********************"); } jsonWebToken = "invalid jwt"; } SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, jsonWebToken, getName()); return simpleAuthenticationInfo; } }
4. 定義一個(gè) WebSubjectFactory, 用來禁用 session
package com.codingos.shirojwt.shiro; import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.SubjectContext; import org.apache.shiro.web.mgt.DefaultWebSubjectFactory; public class CustomWebSubjectFactory extends DefaultWebSubjectFactory { @Override public Subject createSubject(SubjectContext context) { // 禁用session context.setSessionCreationEnabled(false); return super.createSubject(context); } }
5. 定義一個(gè) shiro 的配置類
package com.codingos.shirojwt.shiro; import java.util.HashMap; import java.util.Map; import javax.servlet.Filter; import org.apache.shiro.mgt.DefaultSessionStorageEvaluator; import org.apache.shiro.mgt.DefaultSubjectDAO; import org.apache.shiro.realm.Realm; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.web.mgt.DefaultWebSubjectFactory; import org.springframework.boot.SpringBootConfiguration; import org.springframework.context.annotation.Bean; @SpringBootConfiguration public class ShiroConfig { @Bean public Realm realm() { return new CustomRealm(); } @Bean public DefaultWebSubjectFactory subjectFactory() { return new CustomWebSubjectFactory(); } @Bean public DefaultWebSecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(realm()); securityManager.setSubjectFactory(subjectFactory()); DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO(); DefaultSessionStorageEvaluator sessionStorageEvaluator = new DefaultSessionStorageEvaluator(); // 禁用 session 存儲 sessionStorageEvaluator.setSessionStorageEnabled(false); subjectDAO.setSessionStorageEvaluator(sessionStorageEvaluator); securityManager.setSubjectDAO(subjectDAO); // 禁用 rememberMe securityManager.setRememberMeManager(null); return securityManager; } @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean() { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager()); MapfilterMap = new HashMap<>(); filterMap.put("customFilter", new CustomFilter()); shiroFilterFactoryBean.setFilters(filterMap); Map filterChainDefinitionMap = new HashMap<>(); filterChainDefinitionMap.put("/tologin", "anon"); filterChainDefinitionMap.put("/exception", "anon"); filterChainDefinitionMap.put("/login", "anon"); filterChainDefinitionMap.put("/error", "anon"); filterChainDefinitionMap.put("/todenied", "anon"); filterChainDefinitionMap.put("/**", "customFilter"); // filterChainDefinitionMap.put("/**", "authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); shiroFilterFactoryBean.setLoginUrl("/tologin"); shiroFilterFactoryBean.setSuccessUrl("/indexpage"); shiroFilterFactoryBean.setUnauthorizedUrl("/todenied"); return shiroFilterFactoryBean; } }
在shiro禁用session后, 如果再使用 shiro 的內(nèi)置過濾器 authc, 就會報(bào)錯(cuò), 所以就不用再用 authc, 使用自定義的那個(gè)Filter就行
感謝各位的閱讀,以上就是“shiro集成jwt怎么禁用session”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對shiro集成jwt怎么禁用session這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!