欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring boot整合shiro+jwt實(shí)現(xiàn)前后端分離

 更新時(shí)間:2019年12月16日 09:42:04   作者:期待前進(jìn)  
這篇文章主要為大家詳細(xì)介紹了Spring boot整合shiro+jwt實(shí)現(xiàn)前后端分離,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了Spring boot整合shiro+jwt實(shí)現(xiàn)前后端分離的具體代碼,供大家參考,具體內(nèi)容如下

這里內(nèi)容很少很多都為貼的代碼,具體內(nèi)容我經(jīng)過(guò)了看源碼和帖子加了注釋。帖子就沒(méi)用太多的內(nèi)容

先下載shiro和jwt的jar包

<!-- shiro包 -->
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-spring</artifactId>
  <version>1.4.0</version>
</dependency>
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-ehcache</artifactId>
  <version>1.4.0</version>
</dependency>
<!--JWT依賴-->
<!--JWT-->
<dependency>
  <groupId>com.auth0</groupId>
  <artifactId>java-jwt</artifactId>
  <version>3.4.0</version>
</dependency>
<!--JJWT-->
<dependency>
   <groupId>io.jsonwebtoken</groupId>
   <artifactId>jjwt</artifactId>
   <version>0.9.0</version>
</dependency>

創(chuàng)建shiro的自定義的Realm

代碼如下:

package com.serverprovider.config.shiro.userRealm;
 
 
import com.spring.common.auto.autoUser.AutoUserModel;
import com.spring.common.auto.autoUser.extend.AutoModelExtend;
import com.serverprovider.config.shiro.jwt.JWTCredentialsMatcher;
import com.serverprovider.config.shiro.jwt.JwtToken;
import com.serverprovider.service.loginService.LoginServiceImpl;
import com.util.Redis.RedisUtil;
import com.util.ReturnUtil.SecretKey;
import com.util.encryption.JWTDecodeUtil;
import io.jsonwebtoken.Claims;
import org.apache.log4j.Logger;
import org.apache.shiro.authc.*;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ExceptionHandler;
 
import java.util.HashSet;
import java.util.List;
import java.util.Set;
 
public class UserRealm extends AuthorizingRealm {
 
  private Logger logger = Logger.getLogger(UserRealm.class);
 
 
  @Autowired private LoginServiceImpl loginService;
 
 
  public UserRealm(){
    //這里使用我們自定義的Matcher驗(yàn)證接口
    this.setCredentialsMatcher(new JWTCredentialsMatcher());
  }
 
  /**
   * 必須重寫此方法,不然Shiro會(huì)報(bào)錯(cuò)
   */
  @Override
  public boolean supports(AuthenticationToken token) {
    return token instanceof JwtToken;
  }
 
  /**
   * shiro 身份驗(yàn)證
   * @param token
   * @return boolean
   * @throws AuthenticationException 拋出的異常將有統(tǒng)一的異常處理返回給前端
   *
   */
  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)throws AuthenticationException {
    /**
     * AuthenticationToken
     * JwtToken重寫了AuthenticationToken接口 并創(chuàng)建了一個(gè)接口token的變量
     *  因?yàn)樵趂ilter我們將token存入了JwtToken的token變量中
     *  所以這里直接getToken()就可以獲取前端傳遞的token值
     */
      String JWTtoken = ((JwtToken) token).getToken();
    /**
     * Claims對(duì)象它最終是一個(gè)JSON格式的對(duì)象,任何值都可以添加到其中
     * token解密 轉(zhuǎn)換成Claims對(duì)象
     */
       Claims claims = JWTDecodeUtil.parseJWT(JWTtoken, SecretKey.JWTKey);
      
    /**
     *  根據(jù)JwtUtil加密方法加入的參數(shù)獲取數(shù)據(jù)
     *  查詢數(shù)據(jù)庫(kù)獲得對(duì)象
     *  如為空:拋出異常
     *  如驗(yàn)證失敗拋出 AuthorizationException
     */
      String username = claims.getSubject();
      String password = (String) claims.get("password");
      AutoModelExtend principal = loginService.selectLoginModel(username,password);
      return new SimpleAuthenticationInfo(principal, JWTtoken,"userRealm");
  }
 
 
  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    SimpleAuthorizationInfo info = null;
    /**
     * PrincipalCollection對(duì)象
     * 文檔里面描述:返回從指定的Realm 僅作為Collection 返回的單個(gè)Subject的對(duì)象,如果沒(méi)有來(lái)自該領(lǐng)域的任何對(duì)象,則返回空的Collection。
     * 在登錄接口放入權(quán)限注解返回的錯(cuò)誤信息:Subject.login(AuthenticationToken)或SecurityManager啟用'Remember Me'功能后成功自動(dòng)獲取這些標(biāo)識(shí)主體
     * 當(dāng)調(diào)用Subject.login()方法成功后 PrincipalCollection會(huì)自動(dòng)獲得該對(duì)象 如沒(méi)有認(rèn)證過(guò)或認(rèn)證失敗則返回空的Collection并拋出異常
     * getPrimaryPrincipal():返回在應(yīng)用程序范圍內(nèi)使用的主要對(duì)象,以唯一標(biāo)識(shí)擁有帳戶。
     */
    Object principal = principals.getPrimaryPrincipal();
    /**
     * 得到身份對(duì)象
     * 查詢?cè)撚脩舻臋?quán)限信息
     */
    AutoUserModel user = (AutoUserModel) principal;
    List<String> roleModels = loginService.selectRoleDetails(user.getId());
    try {
    /**
     * 創(chuàng)建一個(gè)Set,來(lái)放置用戶擁有的權(quán)限
     * 創(chuàng)建 SimpleAuthorizationInfo, 并將辦好權(quán)限列表的Set放入.
     */
    Set<String> rolesSet = new HashSet();
    for (String role : roleModels) {
      rolesSet.add(role);
    }
    info = new SimpleAuthorizationInfo();
    info.setStringPermissions(rolesSet);  // 放入權(quán)限信息
  }catch (Exception e){
    throw new AuthenticationException("授權(quán)失敗!");
  }
    return info;
  }
}

這個(gè)授權(quán)方法遇到的坑比較少,就是在最終驗(yàn)證的時(shí)候網(wǎng)上很照抄過(guò)來(lái)的帖子一點(diǎn)都沒(méi)有驗(yàn)證就粘貼賦值,在這里嚴(yán)重吐槽。

在使用jwt最為token而取消shiro傳統(tǒng)的session時(shí)候,我們的需要重寫shiro的驗(yàn)證接口   CredentialsMatcher,在 自定義的realm

中我們加入我們重寫的驗(yàn)證方法,在調(diào)用SimpleAuthenticationInfo()方法進(jìn)行驗(yàn)證的時(shí)候,shiro就會(huì)使用重寫的驗(yàn)證接口。

此處為大坑。

貼上代碼如下:

import com.spring.common.auto.autoUser.extend.AutoModelExtend;
import org.apache.log4j.Logger;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;
 
 
 
/**
 * CredentialsMatcher
 * 接口由類實(shí)現(xiàn),該類可以確定是否提供了AuthenticationToken憑證與系統(tǒng)中存儲(chǔ)的相應(yīng)帳戶的憑證相匹配。
 * Shiro 加密匹配 重寫匹配方法CredentialsMatcher 使用JWTUtil 匹配方式
 */
public class JWTCredentialsMatcher implements CredentialsMatcher {
 
  private Logger logger = Logger.getLogger(JWTCredentialsMatcher.class);
 
  /**
   * Matcher中直接調(diào)用工具包中的verify方法即可
   */
  @Override
  public boolean doCredentialsMatch(AuthenticationToken authenticationToken, AuthenticationInfo authenticationInfo) {
    String token = (String) ((JwtToken)authenticationToken).getToken();
    AutoModelExtend user = (AutoModelExtend)authenticationInfo.getPrincipals().getPrimaryPrincipal();
    //得到DefaultJwtParser
    Boolean verify = JwtUtil.isVerify(token, user);
    logger.info("JWT密碼效驗(yàn)結(jié)果="+verify);
    return verify;
  }
}

shiro的配置項(xiàng)  ShiroConfiguration代碼如下:

import com.serverprovider.config.shiro.shiroSysFile.JwtFilter;
import com.serverprovider.config.shiro.userRealm.UserRealm;
import org.apache.log4j.Logger;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.mgt.SessionStorageEvaluator;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.mgt.DefaultWebSessionStorageEvaluator;
 
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
import javax.servlet.Filter;
import java.util.*;
 
@Configuration
public class ShiroConfiguration {
 
  private Logger logger = Logger.getLogger(ShiroConfiguration.class);
 
 
 
  @Bean("shiroFilter")
  public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
    ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    shiroFilterFactoryBean.setSecurityManager(securityManager);
    //攔截器
    Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
    // 配置不會(huì)被攔截的鏈接 順序判斷
    filterChainDefinitionMap.put("/login/**", "anon");
    // 添加自己的過(guò)濾器并且取名為jwt
    Map<String, Filter> filterMap = new HashMap<String, Filter>();
    filterMap.put("jwt", new JwtFilter());
    shiroFilterFactoryBean.setFilters(filterMap);
    //<!-- 過(guò)濾鏈定義,從上向下順序執(zhí)行,一般將/**放在最為下邊
    filterChainDefinitionMap.put("/**", "jwt");
    shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
 
    return shiroFilterFactoryBean;
  }
 
  /**
   * 禁用session, 不保存用戶登錄狀態(tài)。保證每次請(qǐng)求都重新認(rèn)證。
   * 需要注意的是,如果用戶代碼里調(diào)用Subject.getSession()還是可以用session
   */
  @Bean
  protected SessionStorageEvaluator sessionStorageEvaluator(){
    DefaultWebSessionStorageEvaluator sessionStorageEvaluator = new DefaultWebSessionStorageEvaluator();
    sessionStorageEvaluator.setSessionStorageEnabled(false);
    return sessionStorageEvaluator;
  }
 
 
  @Bean("securityManager")
  public SecurityManager securityManager(UserRealm userRealm) {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    securityManager.setRealm(userRealm);
    /*
     * 關(guān)閉shiro自帶的session,詳情見(jiàn)文檔
     * http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29
     */
    DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
    DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
    defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
    subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
    securityManager.setSubjectDAO(subjectDAO);
 
    return securityManager;
  }
  /**
   * 創(chuàng)建自定義的UserRealm @bean
   */
  @Bean("userRealm")
  public UserRealm shiroRealm() {
    UserRealm shiroRealm = new UserRealm();
    return shiroRealm;
  }
 
 
  //自動(dòng)創(chuàng)建代理,沒(méi)有這個(gè)鑒權(quán)可能會(huì)出錯(cuò)
  @Bean
  public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
    DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
    autoProxyCreator.setProxyTargetClass(true);
    return autoProxyCreator;
  }
  /**
   * 開(kāi)啟shiro aop注解支持.
   * 使用代理方式;所以需要開(kāi)啟代碼支持;
   *
   * @param
   * @return
   */
  @Bean
  public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
    AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
    authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
    return authorizationAttributeSourceAdvisor;
  }

到這里shiro配置就全部完成了

下面開(kāi)始配置jwt:

首先我們需要重寫  AuthenticationToken接口 此接口的作用

負(fù)責(zé)把shiro中username,password生成用于驗(yàn)證的token的封裝類

所有我們需要去實(shí)現(xiàn)這個(gè)接口,封裝我們自己生成的JWT生成的token

import org.apache.shiro.authc.AuthenticationToken;
 
/**
 * AuthenticationToken: shiro中負(fù)責(zé)把username,password生成用于驗(yàn)證的token的封裝類
 * 我們需要自定義一個(gè)對(duì)象用來(lái)包裝token。
 */
public class JwtToken implements AuthenticationToken {
 
  private String token;
 
  public JwtToken(String token) {
    this.token = token;
  }
 
  public String getToken() {
    return token;
  }
 
  public void setToken(String token) {
    this.token = token;
  }
 
  @Override
  public Object getPrincipal() {
    return null;
  }
 
  @Override
  public Object getCredentials() {
    return null;
  }
}

因?yàn)槲覀兪乔昂蠖朔蛛x項(xiàng)目所有我們不存在session驗(yàn)證之類的 所有每次請(qǐng)求都需要攜帶token,所以每次請(qǐng)求我們都需要去驗(yàn)證token的真實(shí)性,所有我們需要去實(shí)現(xiàn)  BasicHttpAuthenticationFilter過(guò)濾器  

BasicHttpAuthenticationFilter繼承 AuthenticatingFilter 過(guò)濾器其能夠自動(dòng)地進(jìn)行基于所述傳入請(qǐng)求的認(rèn)證嘗試。此實(shí)現(xiàn)是每個(gè)基本HTTP身份驗(yàn)證規(guī)范的Java實(shí)現(xiàn)  , 通過(guò)此過(guò)濾器得到HTTP請(qǐng)求資源獲取Authorization傳遞過(guò)來(lái)的token參數(shù)   獲取subject對(duì)象進(jìn)行身份驗(yàn)證

代碼如下:

import com.alibaba.fastjson.JSONObject;
import com.serverprovider.config.shiro.jwt.JwtToken;
import com.util.Util.utilTime;
import org.apache.log4j.Logger;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;
 
/**
 *
 * BasicHttpAuthenticationFilter繼承 AuthenticatingFilter 過(guò)濾器
 * 其能夠自動(dòng)地進(jìn)行基于所述傳入請(qǐng)求的認(rèn)證嘗試。
 *    BasicHttpAuthenticationFilter 基本訪問(wèn)認(rèn)證過(guò)濾器
 *   此實(shí)現(xiàn)是每個(gè)基本HTTP身份驗(yàn)證規(guī)范的Java實(shí)現(xiàn)
 *   通過(guò)此過(guò)濾器得到HTTP請(qǐng)求資源獲取Authorization傳遞過(guò)來(lái)的token參數(shù)
 *   獲取subject對(duì)象進(jìn)行身份驗(yàn)證
 *
 *
 */
public class JwtFilter extends BasicHttpAuthenticationFilter {
 
  Logger logger = Logger.getLogger(JwtFilter.class);
 
  /**
   * 應(yīng)用的HTTP方法列表配置基本身份驗(yàn)證篩選器。
   * 獲取 request 請(qǐng)求 拒絕攔截登錄請(qǐng)求
   * 執(zhí)行登錄認(rèn)證方法
   *
   * @param request
   * @param response
   * @param mappedValue
   * @return
   */
  @Override
  protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
    HttpServletRequest httpServletRequest = (HttpServletRequest) request;
    String requestURI = httpServletRequest.getRequestURI();
    if (requestURI.equals("/user/login/verifyUser") || requestURI.equals("/user/register")) {
      return true;
    } else {
      try {
        executeLogin(request, response);
        return true;
      } catch (Exception e) {
        e.printStackTrace();
        return false;
      }
    }
  }
 
 
 
  /**
   * Authorization攜帶的參數(shù)為token
   * JwtToken實(shí)現(xiàn)了AuthenticationToken接口封裝了token參數(shù)
   * 通過(guò)getSubject方法獲取 subject對(duì)象
   * login()發(fā)送身份驗(yàn)證
   *
   * 為什么需要在Filter中調(diào)用login,不能在controller中調(diào)用login?
   * 由于Shiro默認(rèn)的驗(yàn)證方式是基于session的,在基于token驗(yàn)證的方式中,不能依賴session做為登錄的判斷依據(jù).
   * @param request
   * @param response
   */
  @Override
  protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
    HttpServletResponse httpServletResponse = (HttpServletResponse) response;
    try{
      HttpServletRequest httpServletRequest = (HttpServletRequest) request;
      String token = httpServletRequest.getHeader("Authorization");
      JwtToken jwtToken = new JwtToken(token);
      // 提交給realm進(jìn)行登入,如果錯(cuò)誤他會(huì)拋出異常并被捕獲
      Subject subject = getSubject(request, response);
      subject.login(jwtToken);
      logger.info("JWT驗(yàn)證用戶信息成功");
      // 如果沒(méi)有拋出異常則代表登入成功,返回true
      return true;
      }catch (Exception e){
      /* *
       * 這個(gè)問(wèn)題糾結(jié)了好久
       *   原生的shiro驗(yàn)證失敗會(huì)進(jìn)入全局異常 但是 和JWT結(jié)合以后卻不進(jìn)入了 之前一直想不通
       *   原因是 JWT直接在過(guò)濾器里驗(yàn)證 驗(yàn)證成功與否 都是直接返回到過(guò)濾器中 成功在進(jìn)入controller
       *   失敗直接返回進(jìn)入springboot自定義異常處理頁(yè)面
       */
      JSONObject responseJSONObject = new JSONObject();
      responseJSONObject.put("result","401");
      responseJSONObject.put("resultCode","token無(wú)效,請(qǐng)重新獲取。");
      responseJSONObject.put("resultData","null");
      responseJSONObject.put("resultTime", utilTime.StringDate());
      PrintWriter out = null;
      httpServletResponse.setCharacterEncoding("UTF-8");
      httpServletResponse.setContentType("application/json; charset=utf-8");
      logger.info("返回是");
      logger.info(responseJSONObject.toString());
      out = httpServletResponse.getWriter();
      out.append(responseJSONObject.toString());
    }
  return false;
  }
 
 
 
  /**
   * 對(duì)跨域提供支持
   */
  @Override
  protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
    HttpServletRequest httpServletRequest = (HttpServletRequest) request;
    HttpServletResponse httpServletResponse = (HttpServletResponse) response;
    httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
    httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
    httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
    // 跨域時(shí)會(huì)首先發(fā)送一個(gè)option請(qǐng)求,這里我們給option請(qǐng)求直接返回正常狀態(tài)
    if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
      httpServletResponse.setStatus(HttpStatus.OK.value());
      return false;
    }
    return super.preHandle(request, response);
  }
 
}

貼上 加密解密校驗(yàn)的工具類

import com.spring.common.auto.autoUser.extend.AutoModelExtend;
import com.util.ReturnUtil.SecretKey;
import io.jsonwebtoken.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;;
 
/* @author hw
 * @create 2019-04-16 10.12
 * @desc JWT工具類
 **/
 
public class JwtUtil {
 
 
  /**
   * 用戶登錄成功后生成Jwt
   * 使用Hs256算法 私匙使用用戶密碼
   *
   * @param ttlMillis jwt過(guò)期時(shí)間
   * @param user   登錄成功的user對(duì)象
   * @return
   */
  public static String createJWT(long ttlMillis, AutoModelExtend user) {
    //指定簽名的時(shí)候使用的簽名算法,也就是header那部分,jjwt已經(jīng)將這部分內(nèi)容封裝好了。
    SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
    //生成JWT的時(shí)間
    long nowMillis = System.currentTimeMillis();
    Date now = new Date(nowMillis);
 
    //創(chuàng)建payload的私有聲明(根據(jù)特定的業(yè)務(wù)需要添加,如果要拿這個(gè)做驗(yàn)證,一般是需要和jwt的接收方提前溝通好驗(yàn)證方式的)
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("id", user.getId());
    map.put("username", user.getAuto_username());
    map.put("password", user.getAuto_password());
 
    //生成簽名的時(shí)候使用的秘鑰secret,這個(gè)方法本地封裝了的,一般可以從本地配置文件中讀取,
    // 切記這個(gè)秘鑰不能外露哦。它就是你服務(wù)端的私鑰,在任何場(chǎng)景都不應(yīng)該流露出去。一旦客戶端得知這個(gè)secret, 那就意味著客戶端是可以自我簽發(fā)jwt了。
    String key = SecretKey.JWTKey;
    //生成簽發(fā)人
    String subject = user.getAuto_username();
 
 
    //下面就是在為payload添加各種標(biāo)準(zhǔn)聲明和私有聲明了
    //這里其實(shí)就是new一個(gè)JwtBuilder,設(shè)置jwt的body
    JwtBuilder builder = Jwts.builder()
        //如果有私有聲明,一定要先設(shè)置這個(gè)自己創(chuàng)建的私有的聲明,這個(gè)是給builder的claim賦值,一旦寫在標(biāo)準(zhǔn)的聲明賦值之后,就是覆蓋了那些標(biāo)準(zhǔn)的聲明的
        .setClaims(map)
        //設(shè)置jti(JWT ID):是JWT的唯一標(biāo)識(shí),根據(jù)業(yè)務(wù)需要,這個(gè)可以設(shè)置為一個(gè)不重復(fù)的值,主要用來(lái)作為一次性token,從而回避重放攻擊。
        .setId(UUID.randomUUID().toString())
        //iat: jwt的簽發(fā)時(shí)間
        .setIssuedAt(now)
        //代表這個(gè)JWT的主體,即它的所有人,這個(gè)是一個(gè)json格式的字符串,可以存放什么userid,roldid之類的,作為什么用戶的唯一標(biāo)志。
        .setSubject(subject)
        //設(shè)置簽名使用的簽名算法和簽名使用的秘鑰
        .signWith(signatureAlgorithm, key);
    if (ttlMillis >= 0) {
      long expMillis = nowMillis + ttlMillis;
      Date exp = new Date(expMillis);
      //設(shè)置過(guò)期時(shí)間
      builder.setExpiration(exp);
    }
    return builder.compact();
  }
 
 
  /**
   * 校驗(yàn)token
   * 在這里可以使用官方的校驗(yàn),我這里校驗(yàn)的是token中攜帶的密碼于數(shù)據(jù)庫(kù)一致的話就校驗(yàn)通過(guò)
   *
   * @param token
   * @return
   */
  public static Boolean isVerify(String token, AutoModelExtend userModelExtend) {
    try {
      //得到DefaultJwtParser
      Claims claims = Jwts.parser()
          //設(shè)置簽名的秘鑰
          .setSigningKey(SecretKey.JWTKey)
          //設(shè)置需要解析的jwt
          .parseClaimsJws(token).getBody();
 
      if (claims.get("password").equals(userModelExtend.getAuto_password())) {
        return true;
      }
    } catch (Exception exception) {
      return false;
    }
    return null;
 
  }
 /**
   * Token的解密
   * @param token 加密后的token
   * @param secret 簽名秘鑰,和生成的簽名的秘鑰一模一樣
   * @return
   */
  public static Claims parseJWT(String token, String secret) {
    //得到DefaultJwtParser
    Claims claims = Jwts.parser()
        //設(shè)置簽名的秘鑰
        .setSigningKey(secret)
        //設(shè)置需要解析的jwt
        .parseClaimsJws(token).getBody();
    return claims;
  }
}

到這里shiro jwt整合就完成了。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • java中struts配置

    java中struts配置

    本文給大家詳細(xì)分析了在java項(xiàng)目中配置Struts的方法和示例,十分的簡(jiǎn)單實(shí)用,有需要的小伙伴可以參考下。
    2015-06-06
  • 解決Beanutils.copyproperties實(shí)體類對(duì)象不一致的問(wèn)題

    解決Beanutils.copyproperties實(shí)體類對(duì)象不一致的問(wèn)題

    這篇文章主要介紹了解決Beanutils.copyproperties實(shí)體類對(duì)象不一致的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • 詳解Intellij IDEA的Facets和Artifacts

    詳解Intellij IDEA的Facets和Artifacts

    這篇文章主要介紹了Intellij IDEA的Facets和Artifacts的相關(guān)知識(shí),本文通過(guò)實(shí)例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2020-09-09
  • Dubbo服務(wù)無(wú)法注冊(cè)到ZK上問(wèn)題

    Dubbo服務(wù)無(wú)法注冊(cè)到ZK上問(wèn)題

    這篇文章主要介紹了Dubbo服務(wù)無(wú)法注冊(cè)到ZK上問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Java 詳解如何獲取網(wǎng)絡(luò)接口信息

    Java 詳解如何獲取網(wǎng)絡(luò)接口信息

    讀萬(wàn)卷書不如行萬(wàn)里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)踐中才能獲得能力的提升,本篇文章手把手帶你用Java獲取網(wǎng)絡(luò)接口的信息,大家可以在過(guò)程中查缺補(bǔ)漏,提升水平
    2021-11-11
  • LinkedHashMap如何保證有序問(wèn)題

    LinkedHashMap如何保證有序問(wèn)題

    這篇文章主要介紹了LinkedHashMap如何保證有序問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Gateway網(wǎng)關(guān)源碼解析

    Gateway網(wǎng)關(guān)源碼解析

    這篇文章主要介紹了Gateway微服務(wù)網(wǎng)關(guān),負(fù)載均衡,熔斷和限流,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • SpringMVC Restful api接口實(shí)現(xiàn)的代碼

    SpringMVC Restful api接口實(shí)現(xiàn)的代碼

    本篇文章主要介紹了SpringMVC Restful api接口實(shí)現(xiàn)的代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • java 排序算法之選擇排序

    java 排序算法之選擇排序

    本文主要講解了java 排序算法之選擇排序,選擇排序是最簡(jiǎn)單直觀的一種算法,想要了解相關(guān)知識(shí)的朋友快來(lái)看一看這篇文章吧
    2021-09-09
  • SpringBoot配置文件的加載位置實(shí)例詳解

    SpringBoot配置文件的加載位置實(shí)例詳解

    springboot采納了建立生產(chǎn)就緒spring應(yīng)用程序的觀點(diǎn)。 在一些特殊的情況下,我們需要做修改一些配置,或者需要有自己的配置屬性。接下來(lái)通過(guò)本文給大家介紹SpringBoot配置文件的加載位置,感興趣的朋友一起看看吧
    2018-09-09

最新評(píng)論