SpringCloud service certification (JWT) and springcloudjwt

Source: Internet
Author: User
Tags oauth

SpringCloud service certification (JWT) and springcloudjwt
-JWT

JWT (JSON Web Token) is an open JSON-based standard (RFC 7519) implemented to pass declarations between network application environments ). this token is designed to be compact and secure, and is especially suitable for single-point Logon (SSO) scenarios of distributed sites. JWT statements are generally used to transmit authenticated user identity information between the identity Provider and the service provider, so as to obtain resources from the resource server, you can also add some additional declaration information required by other business logic. The token can be used for authentication or encryption.

-Differences Between JWT and others

Generally, it is highly risky to expose the API directly. If you do not want to mention anything else, just drink a pot if you are directly attacked by machines. In general, the API should be divided into a certain level of permissions, and then a user's authentication will be made available to the user based on the authentication results. Currently, there are several mainstream solutions:

OAuth

OAuth is an open authorization standard that allows users to allow third-party applications to access private resources (such as photos and videos) stored on a service ), you do not need to provide the user name and password to third-party applications.

OAuth allows users to provide a token instead of the user name and password to access the data they store in a specific service provider. Each token authorizes a specific third-party system (for example, a video editing website) at a specific time period (for example, within the next two hours) to access specific resources (for example, only videos in a photo album ). In this way, OAuth allows users to authorize third-party websites to access some specific information they store in another service provider, not all content.

Cookie/Session Auth

The Cookie authentication mechanism creates a Session object for a request authentication on the server, and creates a Cookie object on the client browser; the client brings Cookie objects to match the session objects on the server to implement status management. By default, when we close the browser, the cookie will be deleted. However, you can modify the expire time of the cookie to make the cookie valid for a certain period of time. session-based authentication will inevitably put some pressure on the server (memory storage ), not easy to scale (Distributed session processing required), cross-site request forgery attacks (CSRF)

-Advantages of JWT

1. Compared with session, it does not need to be stored on the server and does not occupy the server memory overhead.

2. stateless and scalable: for example, three machines (A, B, and C) form A server cluster. If the session exists on machine A, the session can only be saved on one of the servers, at this time, you will not be able to access machines B and C, because the Session is not stored on B and C, and the token can be used to verify the validity of the user request, and I will not be able to add a few more machines, this means that the scalability is good.

3. frontend and backend separation. Cross-origin access is supported.

-JWT Composition

{ "iss": "JWT Builder",  "iat": 1416797419,  "exp": 1448333419,  "aud": "www.battcn.com",  "sub": "1837307557@qq.com",  "GivenName": "Levin",  "Surname": "Levin",  "Email": "1837307557@qq.com",  "Role": [ "ADMIN", "MEMBER" ] }
  1. Iss: The issuer of the JWT, whether to use it is optional;
  2. Sub: Specifies whether the JWT is applicable to users;
  3. Aud: The party that receives the JWT. whether to use it is optional;
  4. Exp (expires): When will it expire? Here is a Unix timestamp, and whether to use it is optional;
  5. Iat (issued at): When is it issued (UNIX time)? Is it optional;
  6. Nbf (Not Before): if the current time is earlier than the time in nbf, the Token will Not be accepted. Generally, there will be room for it, for example, a few minutes; whether to use it is optional;

A jwt is actually a string consisting of three parts: Header, load, and signature (sorted in sequence)

JWT Token generator: https://jwt.io/

-Authentication

-Logon authentication

  1. The client sends a POST request to the server and submits the Controller layer for logon.
  2. Call the authentication service to authenticate the user name and password. If the authentication succeeds, the complete user information and corresponding permission information are returned.
  3. Use JWT to build Token for users, permission information, and key
  4. Returns the constructed Token.

-Request Authentication

  1. The client sends a request to the server. The server reads the request header information (request. header) to obtain the Token.
  2. If the Token information is found, JJWT Lib is called to decrypt and decode the Token information based on the signature encryption key in the configuration file;
  3. After decoding and verifying that the signature is passed, verify the exp, nbf, aud, and other information in the Token;
  4. After all the permissions are passed, the permission logic of the requested resource is determined based on the obtained user's role permission information;
  5. If the Permission Logic is determined, the Response is returned through the Response object; otherwise, HTTP 401 is returned;

Invalid Token

Valid Token

-Disadvantages of JWT

If there are advantages, there will be disadvantages. Whether or not they are applicable should be clearly considered, rather than follow the technical trend.

  1. The token is too large to occupy more space.
  2. The token should not store sensitive information.
  3. JWT is not a session. Do not use token as a session.
  4. The issued token cannot be voided, because all authentication information is in JWT. Because it is not in the server status, even if you know that a JWT has been stolen, you cannot invalidate it. You can't do anything before JWT expires (you should definitely set the expiration time.
  5. Similar to cache, because an issued token cannot be voided, you can only endure the "expired" data before it expires (the tokens you put out need to be used in the end with tears ).
-Code (fragment)

Key ing between TokenProperties and application. yml resources for ease of use

@ Configuration @ ConfigurationProperties (prefix = "battcn. security. token ") public class TokenProperties {/*** {@ link com. battcn. security. model. token. token} token expiration time */private Integer expirationTime;/*** issuer */private String issuer;/*** signature KEY {@ link com. battcn. security. model. token. token }. */private String signingKey;/*** {@ link com. battcn. security. model. token. token} refresh expiration time */private Integer refreshExpTime; // get set ...}

Class generated by Token

@ Componentpublic class TokenFactory {private final TokenProperties properties; @ Autowired public TokenFactory (TokenProperties properties) {this. properties = properties;}/*** use JJWT to generate Token * @ param context * @ return */public AccessToken createAccessToken (UserContext context) {Optional. ofNullable (context. getUsername ()). orElseThrow ()-> new IllegalArgumentException ("Cannot create Token without username"); Optional. ofNullable (context. getAuthorities ()). orElseThrow ()-> new IllegalArgumentException ("User doesn't have any privileges"); Claims claims = maid. claims (). setSubject (context. getUsername (); claims. put ("scopes", context. getAuthorities (). stream (). map (Object: toString ). collect (toList (); LocalDateTime currentTime = LocalDateTime. now (); String token = ts. builder (). setClaims (claims ). setIssuer (properties. getIssuer ()). setIssuedAt (Date. from (currentTime. atZone (ZoneId. systemDefault ()). toInstant ())). setExpiration (Date. from (currentTime. plusMinutes (properties. getExpirationTime ()). atZone (ZoneId. systemDefault ()). toInstant ())). signWith (SignatureAlgorithm. HS512, properties. getSigningKey ()). compact (); return new AccessToken (token, claims);}/*** generate refresh RefreshToken * @ param userContext * @ return */public Token createRefreshToken (UserContext userContext) {if (StringUtils. isBlank (userContext. getUsername () {throw new IllegalArgumentException ("Cannot create Token without username");} LocalDateTime currentTime = LocalDateTime. now (); Claims claims = Batch ts. claims (). setSubject (userContext. getUsername (); claims. put ("scopes", Arrays. asList (Scopes. REFRESH_TOKEN.authority (); String token = author ts. builder (). setClaims (claims ). setIssuer (properties. getIssuer ()). setId (UUID. randomUUID (). toString ()). setIssuedAt (Date. from (currentTime. atZone (ZoneId. systemDefault ()). toInstant ())). setExpiration (Date. from (currentTime. plusMinutes (properties. getRefreshExpTime ()). atZone (ZoneId. systemDefault ()). toInstant ())). signWith (SignatureAlgorithm. HS512, properties. getSigningKey ()). compact (); return new AccessToken (token, claims );}}

Configuration file, including token expiration time and key, which can be expanded on its own

Battcn: security: token: expiration-time: 10 # minute 1440 refresh-exp-time: 30 # minute 2880 issuer: http://blog.battcn.com signing-key: battcn

WebSecurityConfig is the key configuration of Spring Security. In Securrty, we can basically define filters to implement the functions we want.

@ Configuration @ EnableWebSecuritypublic class WebSecurityConfig extends websecurityjavaseradapter {public static final String TOKEN_HEADER_PARAM = "X-Authorization"; public static final String Signature = "/api/auth/login "; public static final String TOKEN_BASED_AUTH_ENTRY_POINT = "/api/**"; public static final String MANAGE_TOKEN_BASED_AUTH_ENTRY_POINT = "/manage /**"; public static final String token = "/api/auth/token"; @ Autowired private authentication authenticationEntryPoint; @ Autowired private authentication handler; @ Autowired private authentication failureHandler; @ Autowired private LoginAuthenticationProvider loginAuthenticationProvider; @ Autowired private login handler; @ Autowired private login TokenExtractor; @ Autowired private AuthenticationManager authenticationManager; protected LoginProcessingFilter failed () throws Exception {LoginProcessingFilter filter = new LoginProcessingFilter (optional, optional, optional ); filter. setAuthenticationManager (this. authenticationManager); return filter;} protected TokenAuthenticationProcessingFilter buildTokenAuthenticationProcessingFilter () throws Exception {List <String> list = Lists. newArrayList (outputs, outputs); SkipPathRequestMatcher matcher = new SkipPathRequestMatcher (list); TokenAuthenticationProcessingFilter filter = new TokenAuthenticationProcessingFilter (failureHandler, tokenExtractor, matcher); filter. setAuthenticationManager (this. authenticationManager); return filter;} @ Bean @ Override public AuthenticationManager authenticationManagerBean () throws Exception {return super. authenticationManagerBean () ;}@ Override protected void configure (AuthenticationManagerBuilder auth) {auth. authenticationProvider (loginAuthenticationProvider); auth. authenticationProvider (tokenAuthenticationProvider);} @ Override protected void configure (HttpSecurity http) throws Exception {http. csrf (). disable () // because JWT is used, you can disable csrf here. exceptionHandling (). authenticationEntryPoint (this. authenticationEntryPoint ). and (). sessionManagement (). sessionCreationPolicy (SessionCreationPolicy. STATELESS ). and (). authorizeRequests (). antMatchers (FORM_BASED_LOGIN_ENTRY_POINT ). permitAll () // Login end-point. antMatchers (TOKEN_REFRESH_ENTRY_POINT ). permitAll () // Token refresh end-point. and (). authorizeRequests (). antMatchers (TOKEN_BASED_AUTH_ENTRY_POINT ). authenticated () // Protected API End-points. antMatchers (MANAGE_TOKEN_BASED_AUTH_ENTRY_POINT ). hasAnyRole (RoleEnum. ADMIN. name ()). and (). addFilterBefore (buildLoginProcessingFilter (), UsernamePasswordAuthenticationFilter. class ). addFilterBefore (buildTokenAuthenticationProcessingFilter (), UsernamePasswordAuthenticationFilter. class );}}
-Something to say

JWT code is encapsulated in a simple manner and contains a large amount of content. Therefore, only major fragments are pasted in the article. complete code can be obtained directly from GIT below.

Code in this chapter (battcn-jwt-service): http://xiazai.jb51.net/201801/yuanma/battcn-cloud_jb51.rar

The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.