Spring boot using jwt token authentication mechanism

A, JWT introduction

1. What is the JWT

Json web token (JWT) is a statement in order to pass between the network application execution environment JSON-based development standards (RFC 7519), the token is designed to be compact and safe, especially for distributed sites to a single point of landing ( SSO) scenarios. JWT's statement is generally used between identity providers and service providers to deliver the authenticated user identity information in order to obtain resources from the server, you can also add some additional business logic other necessary information statement, the token also may be directly used for authentication may be encrypted.

2 ,, based token authentication mechanism

Similar to the http protocol is stateless token-based authentication mechanism, which does not require the server to retain the authentication information or session information of the user. This means that the application does not require authentication mechanism tokent opportunity to consider which server the user logs in. This application provides a convenient extension

     Such a process is

  • User requests the server using the username and password
  • Server for authentication of user information
  • The server sends to the user by verifying a token
  • Client storage token, the token and the additional values ​​per request
  • Server authentication token, and returns the data

      This token must be sent with each request to the server, it should be kept in the request header, in addition, the server to support the CORS (Cross-Origin Resource Sharing) strategy, we usually do it in Access-Control-Allow server -Origin: *

3, JWT configuration

JWT is composed of three parts, these three pieces of information constitute a link with JWT text string. like this

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJVc2VySWQiOjEyMywiVXNlck5hbWUiOiJhZG1pbiJ9.Qjw1epD5P6p4Yy2yju3-fkq28PddznqRj3ESfALQy_U

The first part we call the head (header) of the second part of our call load (payload, similar to items carried on the plane), and the third part is the visa (signature)

 header

      JWT two pieces of information carried by the head:

  • Declared type, here is jwt
  • Assertion of the encryption algorithm is usually used directly HMAC SHA256

   Complete the following JSON head like this

 
  1. {

  2. 'typ':'JWT',

  3. 'alg':'HS256'

  4. }

    Then the head base64-encryption (the encrypted can be decrypted symmetric), constitutes the first portion

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

    plyload

      Load local storage is valid information. The name refers specifically to such goods carried on the aircraft, these effective information consists of three parts

  • Standard registration statement
  • Public Statement
  • Private statement 

     Registered mark statement (not recommended mandatory use)

  • iss: jwt issuer
  • sub: jwt for the user
  • aud: the receiving side jwt
  • exp: jwt expiration time, the expiration date must be greater than the issue of time
  • nbf: What time is defined before the jwt are unavailable
  • iat: jwt the issue of time
  • jti: jwt unique identity, is mainly used as a one-time token, in order to avoid a replay attack 

    Public statement:

       Public declarations can add any information, general information about the user to add the necessary information or other business needs, but does not recommend adding sensitive information, because the part of the client can decrypt;

     Private statement

         Private statement is a provider of consumer-defined function declarations and is generally not recommended to store sensitive information, because base64 is decrypted symmetric, meaning that some of the information may be classified in the name of the text information.

     Define a payload

 
  1. {

  2. "sub": "1234567890",

  3. "name": "John Doe",

  4. "admin": true

  5. }

    Base64 then encrypts the obtained part jwt

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

Signature

    The third part is a jwt visa information, this visa information consists of three parts:

  • header (after the base64)
  • payload (after the base64)
  • secred     

       This part needs to use the base64 payload header and the encrypted encryption base64. "" Connected to form a string, and then adding secret encrypted by the encryption header compositions declared, and the third portion constitutes the jwt

 
  1. var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);

  2. var signature = HMACSHA256(encodedString, 'secret'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

    Connection with these three parts into a complete string, constitutes the final jwt ".":

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

     Note: secret is stored on the server side, jwt issued also in the service side, secret is used to authenticate the issuance and jwt of jwt, so it is your server's private key, should not be revealed to any scenario, once the customer end that this secret, it means that the client can self-signed jwt the

 application 

 
  1. 一般是在请求头里加入Authorization,并加上 Bearer 标注:

  2.  
  3. fetch('api/user/1', {

  4. headers: {

  5. 'Authorization': 'Bearer ' + token

  6. }

  7. })

  advantage:

  • Because of the versatility of json, so JWT can support cross-language, like C #, JavaScript, NodeJS, PHP and many other languages ​​can be used
  • Because of the payload portion, JWT business logic may store some other necessary information in its own non-sensitive
  • Ease of transport, JWT configuration is very simple, small occupied bytes, so it is very easy to transport
  • It does not require the server to save session information, so it is easy to extend the application

       Safety-related

  • We should not store sensitive information in a payload portion of jwt, because the portion is part of the client can decrypt
  • Protect the secret private key. The private key is very important
  • If you can, please use the https protocol

Information from the Internet,

Specific view  https://blog.csdn.net/u014799292/article/details/88365086

Second, combat

First introduced into the jar package

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

New jwt of tools

public class JwtTokenUtil {

    Final static String = TOKEN_HEADER public "the Authorization";   
    
    public static String TOKEN_PREFIX Final = "Bearer";
    
    Private static SECRET Final String = "jwtsecrettest";
    
    Private static ISS Final String = "Leopard";
    
    public static Final Long EXPIRATION = 3600L; // expiration time one hour
    
    public static final long EXPIRATION_REMEMBER = 604800L; // select Remember me time after expiration of 7 days
    
    
    / *
     * generate token method
     * @param username 
     * @param isRemenberMe
     * /
    public static String createToken (the above mentioned id String, String username, boolean isRemenberMe) {
        
        Long expiration = isRemenberMe EXPIRATION_REMEMBER: eXPIRATION;?
        
        // String encryId = RCUtils.encry_string(id);
        
        return Jwts.builder().signWith(SignatureAlgorithm.HS512, SECRET)
                .setIssuer(ISS)
                .setId(id)
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + expiration * 1000))
                .compact();
    }
    

    / **
     * Get the user name from the token
     * @param token
     * @return
     * @throws BusinessExpection 
     * /
    public static String the getUsername (String token) throws BusinessExpection {
        return getTokenBody (token) .getSubject ();
    }
    
    / **
     * from token acquired ID, the decryption process while doing
     * @param token
     * @return
     * @throws BusinessExpection 
     * /
    public static String getObjectId (String token) throws BusinessExpection {
        return getTokenBody (token) .getId ();
    }
    
    / **
     * has been expiration
     * @param token
     * @throws expired can not judge only by capturing abnormal ExpiredJwtException
     * @return
     * @throws BusinessExpection 
     */
    @Deprecated
    public static boolean isExpiration(String token) throws BusinessExpection{
        return getTokenBody(token).getExpiration().before(new Date());
    }
    
    
    
    /*
     * 获取token信息,同时也做校验处理
     * 
     */
    public static Claims getTokenBody(String token) throws BusinessExpection {
        
        try {
            return Jwts.parser()
                    .setSigningKey(SECRET)
                    .parseClaimsJws(token)
                    .getBody();
            
        }catch (ExpiredJwtException  expired) {
            // 过期
            throw new BusinessExpection(EmBussinsError.TOKEN_EXPIRED);
        }catch(SignatureException e) {
            //无效
            throw new BusinessExpection(EmBussinsError.INVALID_REQUEST);
        }catch(MalformedJwtException  malformedJwt) {
            //无效
            throw new BusinessExpection(EmBussinsError.INVALID_REQUEST);
        }
        
    }
    
    
}

Unified get token value in baseAction

The first step when a user logs generated token and returns.

@Controller
@RequestMapping("/admin")
public class AdminController extends BaseAction{

    
    @RequestMapping("/login")
    @ResponseBody
    public ResultType login(HttpServletRequest request,HttpServletResponse response) {
        
        String username = request.getParameter("username");
        String pass = request.getParameter("pass");
        
        String token = JwtTokenUtil.createToken("10", username, false);
        
        response.setHeader(JwtTokenUtil.TOKEN_HEADER, JwtTokenUtil.TOKEN_PREFIX+token);
        return ResultType.creat("sussess");
    }
    
    
    @RequestMapping("/adminLoginOut")
    @ResponseBody
    public ResultType adminLoginOut(HttpServletRequest request) throws BusinessExpection {
        
        String userId = getUserid(request);
        
        
        return ResultType.creat("success");
    }
    
}

The test is successful, then return information header kinds of get token encrypted

Took in Log in user testing

When the error will not carry the token

Of course, this error can be your own custom here I am after all tests are written so simple. The main function is to test

When carrying token, the ok

 When the operation was successful will carry the token and token authentication is successful.

Published 20 original articles · won praise 7 · views 10000 +

Guess you like

Origin blog.csdn.net/qrnhhhh/article/details/92644477