This is the 10th day of my participation in the August More Text Challenge

preface

We know that in the project development, background development authority authentication is very important, Springboot commonly familiar authority authentication framework, Shiro, and is springboot family bucket security of course, they each have their own benefits, But I prefer springBoot’s built-in authorization framework

<! Springboot permission authentication -->
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-security</artifactId>
      </dependency>
Copy the code

Natural integration with Springboot, powerful

Quick learning

The main implementation of Spring Security Security authentication, combined with RESTful API style, using stateless environment.

The main implementation is through the URL of the request, through the filter to do different authorization policy operations, provide a method of authentication for the request, and then authentication, authorization successfully returned to the authorization instance information for service invocation.

Token-based authentication is performed as follows:

A user sends requests using a user name and password. Program validation. The program returns a signed token to the client. The client stores tokens and uses them each time to send a request. The server validates the token and returns data. Every request requires a token, so every request authenticates the user, so you have to use caching,

The flow chart

JWT JSON Web Token verification flowchart

Add Spring Security and JWT dependencies

       <! Springboot permission authentication -->
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-security</artifactId>
          </dependency>
         <! - JWT certification - >
         <dependency>
             <groupId>io.jsonwebtoken</groupId>
             <artifactId>jjwt</artifactId>
         </dependency>
Copy the code

Generate JWT toke

I wrote a utility class JwtTokenUtil to generate JWT Toke

package cn.soboys.kmall.security.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

/ * * *@author kenx
 * @version 1.0
 * @date2021/8/5 "*@webSite https://www.soboys.cn/
 */
@Component
public class JwtTokenUtil implements Serializable {

    private static final long serialVersionUID = -2550185165626007488L;

    public static final long JWT_TOKEN_VALIDITY = 7*24*60*60;

    private String secret="TcUF7CC8T3txmfQ38pYsQ3KY";

    public String getUsernameFromToken(String token) {
        return getClaimFromToken(token, Claims::getSubject);
    }


    public String generateToken(String username) {
        Map<String, Object> claims = new HashMap<>();
        return doGenerateToken(claims, username);
    }

    public Boolean validateToken(String token, UserDetails userDetails) {
        final String username = getUsernameFromToken(token);
        return(username.equals(userDetails.getUsername()) && ! isTokenExpired(token)); }public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
        final Claims claims = getAllClaimsFromToken(token);
        return claimsResolver.apply(claims);
    }

    private Claims getAllClaimsFromToken(String token) {
        return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
    }


    private Boolean isTokenExpired(String token) {
        final Date expiration = getExpirationDateFromToken(token);
        return expiration.before(new Date());
    }

    public Date getExpirationDateFromToken(String token) {
        return getClaimFromToken(token, Claims::getExpiration);
    }

    private String doGenerateToken(Map<String, Object> claims, String subject) {
        return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY*1000)).signWith(SignatureAlgorithm.HS512, secret).compact(); }}Copy the code

Injection data source

Spring Security provides the UserDetailsService interface for user authentication, and the UserDetails entity class for storing user information, (user credentials, Permissions, etc.)

Look at the source code

package org.springframework.security.core.userdetails;

public interface UserDetailsService {
    UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
}
Copy the code
package org.springframework.security.core.userdetails;
public interface UserDetails extends Serializable {
    Collection<? extends GrantedAuthority> getAuthorities();

    String getPassword(a);

    String getUsername(a);

    boolean isAccountNonExpired(a);

    boolean isAccountNonLocked(a);

    boolean isCredentialsNonExpired(a);

    boolean isEnabled(a);
}
Copy the code

So we divided it into two steps:

  1. Their ownUserThe entity class inherits Spring SecurityUserDetailsSave related permission information
package cn.soboys.kmall.security.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.*;

/** * <p> * User table * </p> **@author kenx
 * @sinceThe 2021-08-06 * /
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("t_user")
public class User implements Serializable.UserDetails {

    private static final long serialVersionUID = 1L;

    /** * user ID */
    @TableId(value = "USER_ID", type = IdType.AUTO)
    private Long userId;

    /** * User name */
    @TableField("USERNAME")
    private String username;

    /** * Password */
    @TableField("PASSWORD")
    private String password;

    /** * Department ID */
    @TableField("DEPT_ID")
    private Long deptId;

    /** * email */
    @TableField("EMAIL")
    private String email;

    /** ** Contact number */
    @TableField("MOBILE")
    private String mobile;

    /**
     * 状态 0锁定 1有效
     */
    @TableField("STATUS")
    private String status;

    /** * create time */
    @TableField("CREATE_TIME")
    private Date createTime;

    /** * Change the time */
    @TableField("MODIFY_TIME")
    private Date modifyTime;

    /**
     * 最近访问时间
     */
    @TableField("LAST_LOGIN_TIME")
    private Date lastLoginTime;

    /** * Gender 0 male 1 female 2 Confidential */
    @TableField("SSEX")
    private String ssex;

    /** * Whether to enable TAB, 0 to disable 1 to enable */
    @TableField("IS_TAB")
    private String isTab;

    /** * theme */
    @TableField("THEME")
    private String theme;

    /** ** avatar */
    @TableField("AVATAR")
    private String avatar;

    /** * description */
    @TableField("DESCRIPTION")
    private String description;

    @TableField(exist = false)
    private List<Role> roles;


    @TableField(exist = false)
    private Set<String> perms;

    /** * User permission **@return* /
    /*@Override public Collection
       getAuthorities() { List
      
        auths = new ArrayList<>(); List
       
         roles = this.getRoles(); for (Role role : roles) { auths.add(new SimpleGrantedAuthority(role.getRolePerms())); } return auths; } * /
       
      
    @Override
    @JsonIgnore
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> auths = new ArrayList<>();
        Set<String> perms = this.getPerms();
        for (String perm : perms) {
            // If the perms value is null or a null character, an error is reported
            auths.add(new SimpleGrantedAuthority(perm));
        }
        return auths;
    }

    @Override
    @JsonIgnore
    public boolean isAccountNonExpired(a) {
        return true;
    }

    @Override
    @JsonIgnore
    public boolean isAccountNonLocked(a) {
        return true;
    }

    @Override
    @JsonIgnore
    public boolean isCredentialsNonExpired(a) {
        return true;
    }

    @Override
    @JsonIgnore
    public boolean isEnabled(a) {
        return true; }}Copy the code

Note that the User account is locked when logging in to the User

Because when the user entity class implements the UserDetails interface, I automatically implement all the abstract methods, and automatically generate the following four methods, which return false by default,

    @Override
    public boolean isAccountNonExpired(a) {
        return false;
    }
 
    @Override
    public boolean isAccountNonLocked(a) {
        return false;
    }
 
    @Override
    public boolean isCredentialsNonExpired(a) {
        return false;
    }
 
    @Override
    public boolean isEnabled(a) {
        return false;
    }
Copy the code

That’s why, just change their return value to true.

An explanation of several fields in UserDetails:

// Returns the authentication user password, or NULL if it cannot be returned

String getPassword();
String getUsername();
Copy the code

The account is expired. Expiration cannot be verified

boolean isAccountNonExpired();
Copy the code

Specifies whether the user is locked or unlocked. The locked user cannot be authenticated

Boolean isAccountNonLocked ();Copy the code

Credentials (password) indicating whether the user has expired. Expired credentials prevent authentication

boolean isCredentialsNonExpired();
Copy the code

Disabled users cannot be authenticated

boolean isEnabled();
Copy the code
  1. Implementation interfaceloadUserByUsernameMethods inject data validation

Its own IUserService user interface class inherits Spring Security to provide the UserDetailsService interface

public interface IUserService  extends IService<User>, UserDetailsService {

    User getUserByUsername(String username);

   / * * //** * Obtain all user permissions **@param username
     * @return* //* Set
      
        getUserPerms(String username); * /
      

}
Copy the code

And implement it

@Service
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper.User> implements IUserService {
    private final RoleMapper roleMapper;

    @Override
    public User getUserByUsername(String username) {
        return this.baseMapper.selectOne(new QueryWrapper<User>().lambda()
                .eq(User::getUsername, username));
    }


    /** ** when authenticating user details provided by the user@param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = this.getUserByUsername(username);

        if (StrUtil.isBlankIfStr(user)) {
            throw new UsernameNotFoundException("User not found with username: " + username);
        }

        // Get user role information
        List<Role> roles = roleMapper.findUserRolePermsByUserName(username);
        user.setRoles(roles);

        List<String> permList = this.baseMapper.findUserPerms(username);

        / / java8 stream is very convenient
        Set<String> perms = permList.stream().filter(o->StrUtil.isNotBlank(o)).collect(Collectors.toSet());
        user.setPerms(perms);

        // Used to add user permissions. Just add user rights to authorities and you'll be fine.
        // List<SimpleGrantedAuthority> authorities = new ArrayList<>();


        // Used to add user permissions. Just add user rights to authorities and you'll be fine.
        /*for (Role role : roles) { authorities.add(new SimpleGrantedAuthority(role.getRolePerms())); log.info("loadUserByUsername: " + user); } * /
        //user.setAuthorities(authorities); // Used for the value of the @authenticationPrincipal tag at login
        returnuser; }}Copy the code

The loadUserByUsername implementation authenticates the user name and password from the database and obtains user role permission information

Interceptor configuration

Spring Security’s AuthenticationEntryPoint class, which rejects every unauthenticated request and sends error code 401

package cn.soboys.kmall.security.config;

import cn.soboys.kmall.common.ret.Result;
import cn.soboys.kmall.common.ret.ResultCode;
import cn.soboys.kmall.common.ret.ResultResponse;
import cn.soboys.kmall.common.utils.ResponseUtil;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Serializable;

/ * * *@author kenx
 * @version 1.0
 * @date 2021/8/5 22:30
 * @webSitehttps://www.soboys.cn/ * This class inherits Spring Security's AuthenticationEntryPoint class, and * rewrites it. It rejects every unauthenticated request and sends the error code 401. * /
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint.Serializable {

    /** * This class inherits Spring Security's AuthenticationEntryPoint class and re-writes commence. * It rejects every unauthenticated request and sends the error code 401 * *@param httpServletRequest
     * @param httpServletResponse
     * @param e
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        Result result = ResultResponse.failure(ResultCode.UNAUTHORIZED, "Please log in first."); ResponseUtil.responseJson(httpServletResponse, result); }}Copy the code

JwtRequestFilter Any request performs this kind of check to see if the request has a valid JWT token. If it has a valid JWT token, it sets Authentication in the context to specify that the current user is authenticated.

package cn.soboys.kmall.security.config;

import cn.soboys.kmall.common.utils.ConstantFiledUtil;
import cn.soboys.kmall.security.service.IUserService;
import cn.soboys.kmall.security.utils.JwtTokenUtil;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/ * * *@author kenx
 * @version 1.0
 * @date2021/8/5 her *@webSitehttps://www.soboys.cn/ * Any request will perform this class * to check if the request has a valid JWT token. If it has a valid JWT token, * then it sets Authentication in the context to specify that the current user is authenticated. * /
@Component
@Slf4j
public class JwtRequestFilter extends OncePerRequestFilter {

    // User data source
    private IUserService userService;
    // Generate JWT tokens
    private  JwtTokenUtil jwtTokenUtil;

    public JwtRequestFilter(IUserService userService,JwtTokenUtil jwtTokenUtil) {
        this.userService = userService;
        this.jwtTokenUtil = jwtTokenUtil;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        final String requestTokenHeader = request.getHeader(ConstantFiledUtil.AUTHORIZATION_TOKEN);

        String username = null;
        String jwtToken = null;
        // JWT Token is in the form "Bearer token". Remove Bearer word and get only the Token
        if(requestTokenHeader ! =null && requestTokenHeader.startsWith("Bearer ")) {
            jwtToken = requestTokenHeader.substring(7);
            try {
                username = jwtTokenUtil.getUsernameFromToken(jwtToken);
            } catch (IllegalArgumentException e) {
                log.error("Unable to get JWT Token");
            } catch (ExpiredJwtException e) {
                log.error("JWT Token has expired"); }}else {
            //logger.warn("JWT Token does not begin with Bearer String");
        }

        //Once we get the token validate it.
        if(username ! =null && SecurityContextHolder.getContext().getAuthentication() == null) {

            UserDetails userDetails = this.userService.loadUserByUsername(username);

            // if token is valid configure Spring Security to manually set authentication
            if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {

                // Save user information and permission information
                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities());
                usernamePasswordAuthenticationToken
                        .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                // After setting the Authentication in the context, we specify
                // that the current user is authenticated. So it passes the Spring Security Configurations successfully.SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); } } filterChain.doFilter(request, response); }}Copy the code

Configure the Spring Security configuration class SecurityConfig

  1. Custom Spring Security when we need to inherit from WebSecurityConfigurerAdapter to complete, relevant configuration rewrite the corresponding method

  2. The BCryptPasswordEncoder password is used for encryption

  3. Add our own custom authentication by overriding the configure method.

package cn.soboys.kmall.security.config;


import cn.soboys.kmall.security.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import java.util.Set;

/ * * *@author kenx
 * @version 1.0
 * @date 2021/8/6 17:27
 * @webSite https://www.soboys.cn/
 */
@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true) // Control permission annotations
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
    private IUserService userService;
    private JwtRequestFilter jwtRequestFilter;


    public SecurityConfig(JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint, IUserService userService, JwtRequestFilter jwtRequestFilter) {
        this.jwtAuthenticationEntryPoint = jwtAuthenticationEntryPoint;
        this.userService = userService;
        this.jwtRequestFilter = jwtRequestFilter;
    }


    /** * 1) HttpSecurity supports CORS. * 2) CRSF is enabled by default. Because the thymeleaf template is not used (_cSRf parameter will be automatically injected), * you need to disable CSRF first. Otherwise, the _cSRF parameter will be required during login, resulting in login failure. * 3) antMatchers: match "/" path, do not need permission to access, match "/user" and all paths below, * all need "user" permission * 4) configure login address and exit address */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // We don't need CSRF for this example
        http.csrf().disable()
                // dont authenticate this particular request
                .authorizeRequests().antMatchers("/"."/*.html"."/favicon.ico"."/css/**"."/js/**"."/fonts/**"."/layui/**"."/img/**"."/v3/api-docs/**"."/swagger-resources/**"."/webjars/**"."/pages/**"."/druid/**"."/statics/**"."/login"."/register").permitAll().
                // all other requests need to be authenticated
                        anyRequest().authenticated().and().
                // make sure we use stateless session; session won't be used to
                // store user's state.
                // Override the default login
                        exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and().sessionManagement()
                // Token-based, so no session is required
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);


        // Add a filter to validate the tokens with every request
        http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    }


    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean(a) throws Exception {
        return super.authenticationManagerBean();
    }

    /** * Password verification **@param auth
     * @throws Exception
     */
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        // configure AuthenticationManager so that it knows from where to load
        // user for matching credentials
        // Use BCryptPasswordEncoder
        auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
    }

    /** * Password encryption verification **@return* /
    @Bean
    public PasswordEncoder passwordEncoder(a) {
        return newBCryptPasswordEncoder(); }}Copy the code

The specific application

package cn.soboys.kmall.security.controller;

import cn.hutool.core.util.StrUtil;
import cn.soboys.kmall.common.exception.BusinessException;
import cn.soboys.kmall.common.ret.ResponseResult;
import cn.soboys.kmall.common.ret.Result;
import cn.soboys.kmall.common.ret.ResultResponse;
import cn.soboys.kmall.security.entity.User;
import cn.soboys.kmall.security.service.IUserService;
import cn.soboys.kmall.security.utils.EncryptPwdUtil;
import cn.soboys.kmall.security.utils.JwtTokenUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.Date;
import java.util.Objects;

/ * * *@author kenx
 * @version 1.0
 * @date 2021/8/6 12:30
 * @webSite https://www.soboys.cn/
 */
@RestController
@ResponseResult
@Validated
@RequiredArgsConstructor
@API (tags = "login interface ")
public class LoginController {
    private final IUserService userService;
    // Authentication management, authentication user province
    private final AuthenticationManager authenticationManager;
    private final JwtTokenUtil jwtTokenUtil;
    // Own data source
    private final UserDetailsService jwtInMemoryUserDetailsService;




    @PostMapping("/login")
    @apiOperation (" User login ")
    @SneakyThrows
    public Result login(@NotBlank @RequestParam String username,
                        @NotBlank @RequestParam String password) {


        Authentication authentication= this.authenticate(username, password);

        String user = authentication.getName();

        final String token = jwtTokenUtil.generateToken(user);
        // Update the last login time of the user
        User u = new User();
        u.setLastLoginTime(new Date());
        userService.update(u, new UpdateWrapper<User>().lambda().eq(User::getUsername, username));
        return ResultResponse.success("Bearer " + token);
    }

    @PostMapping("/register")
    @apiOperation (" User registration ")
    public Result register(@NotEmpty @RequestParam String username, @NotEmpty @RequestParam String password) {
        User user = userService.getUserByUsername(username);

        if(! StrUtil.isBlankIfStr(user)) {throw new BusinessException("User already exists");
        }
        User u = new User();
        u.setPassword(EncryptPwdUtil.encryptPassword(password));
        u.setUsername(username);
        u.setCreateTime(new Date());
        u.setModifyTime(new Date());
        u.setStatus("1");
        userService.save(u);
        return ResultResponse.success();

    }


    private Authentication authenticate(String username, String password) throws Exception {
        Authentication authentication = null;
        try {
            //security Authenticates the user
            authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
        } catch (DisabledException e) {
            throw new BusinessException("User does not save");
        } catch (BadCredentialsException e) {
            throw new BusinessException("Username and password error");
        }

        returnauthentication; }}Copy the code

Insight into the

Spring Security configuration description

  1. @enablewebSecurity Enables permission authentication
  2. @ EnableGlobalMethodSecurity open authority annotation certification (prePostEnabled = true)
  3. Configure the configuration
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // We don't need CSRF for this example
        http.csrf().disable()
                // dont authenticate this particular request
                .authorizeRequests().antMatchers("/"."/*.html"."/favicon.ico"."/css/**"."/js/**"."/fonts/**"."/layui/**"."/img/**"."/v3/api-docs/**"."/swagger-resources/**"."/webjars/**"."/pages/**"."/druid/**"."/statics/**"."/login"."/register").permitAll().
                // all other requests need to be authenticated
                        anyRequest().authenticated().and().
                // make sure we use stateless session; session won't be used to
                // store user's state.
                // Override the default login
                        exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and().sessionManagement()
                // Token-based, so no session is required
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);


        // Add a filter to validate the tokens with every request
        http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    }

Copy the code

reference

  1. Spring Security permission authentication
  2. HTTP Basic authentication for springSecurity
  3. SpringBoot Security + JWT Hello World