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

詳解Spring Boot實(shí)戰(zhàn)之Filter實(shí)現(xiàn)使用JWT進(jìn)行接口認(rèn)證

 更新時(shí)間:2017年07月14日 16:10:44   作者:sun_t89  
本篇文章主要介紹了詳解Spring Boot實(shí)戰(zhàn)之Filter實(shí)現(xiàn)使用JWT進(jìn)行接口認(rèn)證,具有一定的參考價(jià)值,有興趣的可以了解一下

本文介紹了spring Boot實(shí)戰(zhàn)之Filter實(shí)現(xiàn)使用JWT進(jìn)行接口認(rèn)證,分享給大家

jwt(json web token)

用戶發(fā)送按照約定,向服務(wù)端發(fā)送 Header、Payload 和 Signature,并包含認(rèn)證信息(密碼),驗(yàn)證通過(guò)后服務(wù)端返回一個(gè)token,之后用戶使用該token作為登錄憑證,適合于移動(dòng)端和api

jwt使用流程

本文示例接上面幾篇文章中的代碼進(jìn)行編寫(xiě),請(qǐng)閱讀本文的同時(shí)可以參考前面幾篇文章

1、添加依賴庫(kù)jjwt,本文中構(gòu)造jwt及解析jwt都使用了jjwt庫(kù)

<dependency> 
  <groupId>io.jsonwebtoken</groupId> 
  <artifactId>jjwt</artifactId> 
  <version>0.6.0</version> 
</dependency> 

2、添加登錄獲取token時(shí),所需要的認(rèn)證信息類(lèi)LoginPara.Java

package com.xiaofangtech.sunt.jwt; 
 
public class LoginPara { 
  private String clientId; 
  private String userName; 
  private String password; 
  private String captchaCode; 
  private String captchaValue; 
   
  public String getClientId() { 
    return clientId; 
  } 
  public void setClientId(String clientId) { 
    this.clientId = clientId; 
  } 
  public String getUserName() { 
    return userName; 
  } 
  public void setUserName(String userName) { 
    this.userName = userName; 
  } 
  public String getPassword() { 
    return password; 
  } 
  public void setPassword(String password) { 
    this.password = password; 
  } 
  public String getCaptchaCode() { 
    return captchaCode; 
  } 
  public void setCaptchaCode(String captchaCode) { 
    this.captchaCode = captchaCode; 
  } 
  public String getCaptchaValue() { 
    return captchaValue; 
  } 
  public void setCaptchaValue(String captchaValue) { 
    this.captchaValue = captchaValue; 
  } 
} 

3、添加構(gòu)造jwt及解析jwt的幫助類(lèi)JwtHelper.java

package com.xiaofangtech.sunt.jwt; 
 
import java.security.Key; 
import java.util.Date; 
 
import javax.crypto.spec.SecretKeySpec; 
import javax.xml.bind.DatatypeConverter; 
 
import io.jsonwebtoken.Claims; 
import io.jsonwebtoken.JwtBuilder; 
import io.jsonwebtoken.Jwts; 
import io.jsonwebtoken.SignatureAlgorithm; 
 
public class JwtHelper { 
  public static Claims parseJWT(String jsonWebToken, String base64Security){ 
    try 
    { 
      Claims claims = Jwts.parser() 
            .setSigningKey(DatatypeConverter.parseBase64Binary(base64Security)) 
            .parseClaimsJws(jsonWebToken).getBody(); 
      return claims; 
    } 
    catch(Exception ex) 
    { 
      return null; 
    } 
  } 
   
  public static String createJWT(String name, String userId, String role,  
      String audience, String issuer, long TTLMillis, String base64Security)  
  { 
    SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; 
      
    long nowMillis = System.currentTimeMillis(); 
    Date now = new Date(nowMillis); 
      
    //生成簽名密鑰 
    byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(base64Security); 
    Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName()); 
      
     //添加構(gòu)成JWT的參數(shù) 
    JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT") 
                    .claim("role", role) 
                    .claim("unique_name", name) 
                    .claim("userid", userId) 
                    .setIssuer(issuer) 
                    .setAudience(audience) 
                    .signWith(signatureAlgorithm, signingKey); 
     //添加Token過(guò)期時(shí)間 
    if (TTLMillis >= 0) { 
      long expMillis = nowMillis + TTLMillis; 
      Date exp = new Date(expMillis); 
      builder.setExpiration(exp).setNotBefore(now); 
    } 
      
     //生成JWT 
    return builder.compact(); 
  }  
} 

4、添加token返回結(jié)果類(lèi)AccessToken.java

package com.xiaofangtech.sunt.jwt; 
 
public class AccessToken { 
  private String access_token; 
  private String token_type; 
  private long expires_in; 
  public String getAccess_token() { 
    return access_token; 
  } 
  public void setAccess_token(String access_token) { 
    this.access_token = access_token; 
  } 
  public String getToken_type() { 
    return token_type; 
  } 
  public void setToken_type(String token_type) { 
    this.token_type = token_type; 
  } 
  public long getExpires_in() { 
    return expires_in; 
  } 
  public void setExpires_in(long expires_in) { 
    this.expires_in = expires_in; 
  } 
} 

5、添加獲取token的接口,通過(guò)傳入用戶認(rèn)證信息(用戶名、密碼)進(jìn)行認(rèn)證獲取

package com.xiaofangtech.sunt.jwt; 
 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.web.bind.annotation.RequestBody; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RestController; 
 
import com.xiaofangtech.sunt.bean.UserInfo; 
import com.xiaofangtech.sunt.repository.UserInfoRepository; 
import com.xiaofangtech.sunt.utils.MyUtils; 
import com.xiaofangtech.sunt.utils.ResultMsg; 
import com.xiaofangtech.sunt.utils.ResultStatusCode; 
 
@RestController 
public class JsonWebToken { 
  @Autowired 
  private UserInfoRepository userRepositoy; 
   
  @Autowired 
  private Audience audienceEntity; 
   
  @RequestMapping("oauth/token") 
  public Object getAccessToken(@RequestBody LoginPara loginPara) 
  { 
    ResultMsg resultMsg; 
    try 
    { 
      if(loginPara.getClientId() == null  
          || (loginPara.getClientId().compareTo(audienceEntity.getClientId()) != 0)) 
      { 
        resultMsg = new ResultMsg(ResultStatusCode.INVALID_CLIENTID.getErrcode(),  
            ResultStatusCode.INVALID_CLIENTID.getErrmsg(), null); 
        return resultMsg; 
      } 
       
      //驗(yàn)證碼校驗(yàn)在后面章節(jié)添加 
       
       
      //驗(yàn)證用戶名密碼 
      UserInfo user = userRepositoy.findUserInfoByName(loginPara.getUserName()); 
      if (user == null) 
      { 
        resultMsg = new ResultMsg(ResultStatusCode.INVALID_PASSWORD.getErrcode(), 
            ResultStatusCode.INVALID_PASSWORD.getErrmsg(), null); 
        return resultMsg; 
      } 
      else 
      { 
        String md5Password = MyUtils.getMD5(loginPara.getPassword()+user.getSalt()); 
         
        if (md5Password.compareTo(user.getPassword()) != 0) 
        { 
          resultMsg = new ResultMsg(ResultStatusCode.INVALID_PASSWORD.getErrcode(), 
              ResultStatusCode.INVALID_PASSWORD.getErrmsg(), null); 
          return resultMsg; 
        } 
      } 
       
      //拼裝accessToken 
      String accessToken = JwtHelper.createJWT(loginPara.getUserName(), String.valueOf(user.getName()), 
          user.getRole(), audienceEntity.getClientId(), audienceEntity.getName(), 
          audienceEntity.getExpiresSecond() * 1000, audienceEntity.getBase64Secret()); 
       
      //返回accessToken 
      AccessToken accessTokenEntity = new AccessToken(); 
      accessTokenEntity.setAccess_token(accessToken); 
      accessTokenEntity.setExpires_in(audienceEntity.getExpiresSecond()); 
      accessTokenEntity.setToken_type("bearer"); 
      resultMsg = new ResultMsg(ResultStatusCode.OK.getErrcode(),  
          ResultStatusCode.OK.getErrmsg(), accessTokenEntity); 
      return resultMsg; 
       
    } 
    catch(Exception ex) 
    { 
      resultMsg = new ResultMsg(ResultStatusCode.SYSTEM_ERR.getErrcode(),  
          ResultStatusCode.SYSTEM_ERR.getErrmsg(), null); 
      return resultMsg; 
    } 
  } 
} 

6、添加使用jwt認(rèn)證的filter

package com.xiaofangtech.sunt.filter; 
 
import java.io.IOException; 
 
import javax.servlet.Filter; 
import javax.servlet.FilterChain; 
import javax.servlet.FilterConfig; 
import javax.servlet.ServletException; 
import javax.servlet.ServletRequest; 
import javax.servlet.ServletResponse; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.web.context.support.SpringBeanAutowiringSupport; 
 
import com.fasterxml.jackson.databind.ObjectMapper; 
import com.xiaofangtech.sunt.jwt.Audience; 
import com.xiaofangtech.sunt.jwt.JwtHelper; 
import com.xiaofangtech.sunt.utils.ResultMsg; 
import com.xiaofangtech.sunt.utils.ResultStatusCode; 
 
public class HTTPBearerAuthorizeAttribute implements Filter{ 
  @Autowired 
  private Audience audienceEntity; 
 
  @Override 
  public void init(FilterConfig filterConfig) throws ServletException { 
    // TODO Auto-generated method stub 
    SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, 
        filterConfig.getServletContext()); 
     
  } 
 
  @Override 
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
      throws IOException, ServletException { 
    // TODO Auto-generated method stub 
     
    ResultMsg resultMsg; 
    HttpServletRequest httpRequest = (HttpServletRequest)request; 
    String auth = httpRequest.getHeader("Authorization"); 
    if ((auth != null) && (auth.length() > 7)) 
    { 
      String HeadStr = auth.substring(0, 6).toLowerCase(); 
      if (HeadStr.compareTo("bearer") == 0) 
      { 
         
        auth = auth.substring(7, auth.length());  
        if (JwtHelper.parseJWT(auth, audienceEntity.getBase64Secret()) != null) 
        { 
          chain.doFilter(request, response); 
          return; 
        } 
      } 
    } 
     
    HttpServletResponse httpResponse = (HttpServletResponse) response; 
    httpResponse.setCharacterEncoding("UTF-8");  
    httpResponse.setContentType("application/json; charset=utf-8");  
    httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 
 
    ObjectMapper mapper = new ObjectMapper(); 
     
    resultMsg = new ResultMsg(ResultStatusCode.INVALID_TOKEN.getErrcode(), ResultStatusCode.INVALID_TOKEN.getErrmsg(), null); 
    httpResponse.getWriter().write(mapper.writeValueAsString(resultMsg)); 
    return; 
  } 
 
  @Override 
  public void destroy() { 
    // TODO Auto-generated method stub 
     
  } 
} 

7、在入口處注冊(cè)filter

package com.xiaofangtech.sunt; 
 
import java.util.ArrayList; 
import java.util.List; 
 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.boot.context.embedded.FilterRegistrationBean; 
import org.springframework.boot.context.properties.EnableConfigurationProperties; 
import org.springframework.context.annotation.Bean; 
 
import com.xiaofangtech.sunt.filter.HTTPBasicAuthorizeAttribute; 
import com.xiaofangtech.sunt.filter.HTTPBearerAuthorizeAttribute; 
import com.xiaofangtech.sunt.jwt.Audience; 
 
@SpringBootApplication 
@EnableConfigurationProperties(Audience.class) 
public class SpringRestApplication { 
 
  public static void main(String[] args) { 
    SpringApplication.run(SpringRestApplication.class, args); 
  } 
   
  @Bean 
  public FilterRegistrationBean basicFilterRegistrationBean() { 
    FilterRegistrationBean registrationBean = new FilterRegistrationBean(); 
    HTTPBasicAuthorizeAttribute httpBasicFilter = new HTTPBasicAuthorizeAttribute(); 
    registrationBean.setFilter(httpBasicFilter); 
    List<String> urlPatterns = new ArrayList<String>(); 
    urlPatterns.add("/user/getuser"); 
    registrationBean.setUrlPatterns(urlPatterns); 
    return registrationBean; 
  } 
   
  @Bean 
  public FilterRegistrationBean jwtFilterRegistrationBean(){ 
    FilterRegistrationBean registrationBean = new FilterRegistrationBean(); 
    HTTPBearerAuthorizeAttribute httpBearerFilter = new HTTPBearerAuthorizeAttribute(); 
    registrationBean.setFilter(httpBearerFilter); 
    List<String> urlPatterns = new ArrayList<String>(); 
    urlPatterns.add("/user/getusers"); 
    registrationBean.setUrlPatterns(urlPatterns); 
    return registrationBean; 
  } 
} 

8、添加獲取md5的方法類(lèi)MyUtils

package com.xiaofangtech.sunt.utils; 
 
import java.security.MessageDigest; 
 
public class MyUtils { 
  public static String getMD5(String inStr) { 
    MessageDigest md5 = null; 
    try { 
      md5 = MessageDigest.getInstance("MD5"); 
    } catch (Exception e) { 
       
      e.printStackTrace(); 
      return ""; 
    } 
    char[] charArray = inStr.toCharArray(); 
    byte[] byteArray = new byte[charArray.length]; 
  
    for (int i = 0; i < charArray.length; i++) 
      byteArray[i] = (byte) charArray[i]; 
  
    byte[] md5Bytes = md5.digest(byteArray); 
  
    StringBuffer hexValue = new StringBuffer(); 
  
    for (int i = 0; i < md5Bytes.length; i++) { 
      int val = ((int) md5Bytes[i]) & 0xff; 
      if (val < 16) 
        hexValue.append("0"); 
      hexValue.append(Integer.toHexString(val)); 
    } 
  
    return hexValue.toString(); 
  } 
} 

9、在返回信息類(lèi)中補(bǔ)充添加錯(cuò)誤碼

INVALID_CLIENTID(30003, "Invalid clientid"), 
INVALID_PASSWORD(30004, "User name or password is incorrect"), 
INVALID_CAPTCHA(30005, "Invalid captcha or captcha overdue"), 
INVALID_TOKEN(30006, "Invalid token"); 

10、代碼中涉及的Audience類(lèi),在上一篇文章中定義,本文不再重復(fù)說(shuō)明

11、代碼整體結(jié)構(gòu)

 

12、測(cè)試

1) 獲取token,傳入用戶認(rèn)證信息


認(rèn)證通過(guò)返回token信息


2) 使用上面獲取的token進(jìn)行接口調(diào)用

未使用token,獲取token錯(cuò)誤,或者token過(guò)期時(shí)


使用正確的token時(shí)

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

相關(guān)文章

  • 學(xué)生視角手把手帶你寫(xiě)Java?線程池初版

    學(xué)生視角手把手帶你寫(xiě)Java?線程池初版

    作者是一個(gè)來(lái)自河源的大三在校生,以下筆記都是作者自學(xué)之路的一些淺薄經(jīng)驗(yàn),如有錯(cuò)誤請(qǐng)指正,將來(lái)會(huì)不斷的完善筆記,幫助更多的Java愛(ài)好者入門(mén)
    2022-03-03
  • Springboot @Value使用代碼實(shí)例

    Springboot @Value使用代碼實(shí)例

    這篇文章主要介紹了Springboot @Value使用代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • 詳解Java中接口的定義與實(shí)例代碼

    詳解Java中接口的定義與實(shí)例代碼

    這篇文章主要介紹了詳解Java中接口的定義與實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • java一個(gè)接口多個(gè)實(shí)現(xiàn)類(lèi)的調(diào)用方式

    java一個(gè)接口多個(gè)實(shí)現(xiàn)類(lèi)的調(diào)用方式

    這篇文章主要給大家介紹了關(guān)于java一個(gè)接口多個(gè)實(shí)現(xiàn)類(lèi)的調(diào)用方式的相關(guān)資料,經(jīng)測(cè)試確認(rèn),當(dāng)一個(gè)接口有多個(gè)實(shí)現(xiàn)時(shí),調(diào)用時(shí)只會(huì)執(zhí)行一個(gè),有時(shí)候需要多個(gè)實(shí)現(xiàn)調(diào)用,需要的朋友可以參考下
    2023-09-09
  • java Array和Arrays的區(qū)別總結(jié)

    java Array和Arrays的區(qū)別總結(jié)

    在本篇內(nèi)容里小編給大家整理的是一篇關(guān)于java Array和Arrays的區(qū)別總結(jié)內(nèi)容,有需要的朋友們可以學(xué)習(xí)下。
    2021-03-03
  • java 微信隨機(jī)紅包算法代碼實(shí)例

    java 微信隨機(jī)紅包算法代碼實(shí)例

    這篇文章主要介紹了java 微信隨機(jī)紅包算法的相關(guān)資料,并附實(shí)例代碼,需要的朋友可以參考下
    2016-10-10
  • Java 10 局部變量類(lèi)型推斷淺析

    Java 10 局部變量類(lèi)型推斷淺析

    這篇文章主要介紹了Java 10 局部變量類(lèi)型推斷淺析,Java 10 引進(jìn)一種新的閃閃發(fā)光的特性叫做局部變量類(lèi)型推斷。文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,,需要的朋友可以參考下
    2019-06-06
  • Feign遠(yuǎn)程調(diào)用Multipartfile參數(shù)處理

    Feign遠(yuǎn)程調(diào)用Multipartfile參數(shù)處理

    這篇文章主要介紹了Feign遠(yuǎn)程調(diào)用Multipartfile參數(shù)處理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • java實(shí)現(xiàn)下載文件到默認(rèn)瀏覽器路徑

    java實(shí)現(xiàn)下載文件到默認(rèn)瀏覽器路徑

    這篇文章主要介紹了java實(shí)現(xiàn)下載文件到默認(rèn)瀏覽器路徑,具有很好的參考價(jià)值,希望對(duì)的大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Java微信公眾平臺(tái)開(kāi)發(fā)(14) 微信web開(kāi)發(fā)者工具使用

    Java微信公眾平臺(tái)開(kāi)發(fā)(14) 微信web開(kāi)發(fā)者工具使用

    這篇文章主要為大家詳細(xì)介紹了Java微信公眾平臺(tái)開(kāi)發(fā)第十四步,微信web開(kāi)發(fā)者工具的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04

最新評(píng)論