This article has participated in the activity of “New person creation Ceremony”, and started the road of digging gold creation together.

In the previous article “Spring Cloud Based Simple JWT Issue and Refresh Construction Method”, we implemented simple token issue and refresh, and can block requests without tokens or token expiration. However, it is not detailed enough to control whether requests carrying legitimate tokens have access to certain interfaces, which is similar to the @preauthorize (“hasAuthority(‘admin’)”) annotation in Spring Cloud Security.

This article uses interceptors in the Spring Cloud for a similar purpose. Here’s how:

  1. First define annotationsHasRole
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface HasRole {

    String role(a) default "";

}
Copy the code
  1. And then we store itrolePosition the way, if attention is paid to security, to preventtokenInformation tampered with by the client can be issued beforetokenTo save the role informationredisIn the. In order to demonstrate the interceptor function, the implementation method is direct deposittokenIn the payload, soJwtModelRewrite as follows:
public class JwtModel {

    public JwtModel(Integer id, String userName){
        this.userName = userName;
        this.id = id;
    }
    
    public JwtModel(Integer id, String userName, List<String> roles){
        this.userName = userName;
        this.id = id;
        this.roles = roles;
    }
    
    private Integer id;

    private String userName;
    
    private List<String> roles;

    public Integer getId(a){
        return this.id;
    }
    
    public void setId(Integer id){
        this.id = id;
    }
    
    public String getUserName(a){
        return this.userName;
    }
    
    public void setUserName(String userName){
        this.userName = userName;
    }
    
    public List<String> getRoles(a){
        return this.roles;
    }
    
    public void setRoles(List<String> roles){
        this.roles = roles; }}Copy the code
  1. Add filter resolutiontokenTo store informationrequestInformation to facilitate subsequent calls
// The filter should come after the spring Cloud Gateway's global filter
@Order(1)
@Component
public class AttributeFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        if (request.getHeader("Authorization") != null){
            JwtModel jwtModel = JwtUtil.getModel(request.getHeader("Authorization").toString());
            servletRequest.setAttribute("id", jwtModel.getId());
            if(jwtModel.getRoles ! =null){
                servletRequest.setAttribute("roles", jwtModel.getRoles()); } } filterChain.doFilter(servletRequest, servletResponse); }}Copy the code
  1. Then there is interceptor implementation and configuration
public class HasRoleInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        HasRole hasRole = handlerMethod.getMethodAnnotation(HasRole.class);
        if(hasRole == null) {return true;
        }
        String role = hasRole.role();
        if(role == "") {return true;
        }
        if(request.getAttribute("roles") = =null){
            setRes(response, new CommonResult(403."No role permissions currently available"));
        }
        List<String> roleList = (List<String>) request.getAttribute("roles");
        if(roleList.contains(role)){
            return true;
        } else {
            setRes(response, new CommonResult(403."No role permissions currently available"));
            return false; }}// Set the return information
    private void setRes(HttpServletResponse response, CommonResult cr){
        ObjectMapper om = new ObjectMapper();
        response.setStatus(HttpStatus.OK.value());
        response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        try{
            om.writeValue(response.getWriter(), cr);
        } catch(IOException e){ System.out.print(e.getMessage()); }}}Copy the code

Add interceptor configuration

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(newHasRoleInterceptor()); }}Copy the code
  1. The specific use
@RestController
@RefreshScope
public class TestController{

    @GetMapping("/roletest")
    @HasRole(role = "admin")
    public CommonResult roleTest(HttpServletRequest request){
        return new CommonResult(200."SUCCESS", request.getAttribute("id") + " has role"); }}Copy the code

The above method flow can block access of roles without specific permissions at the level of specific interface methods, and more detailed implementation and utilization of token functions.

* Note: The unimplemented classes or methods used in the above code can be found in the previous article “Simple JWT Issuance and Refresh Build Method based on Spring Cloud”.