美文网首页
SpringBoot Security JWT 登录授权认证

SpringBoot Security JWT 登录授权认证

作者: kaixingdeshui | 来源:发表于2020-11-24 20:12 被阅读0次

SpringBoot2.X Security JWT 登录授权认证

目前在java后端的开发项目中,授权认证这个功能基本是必备的,这里只讲常用的登录授权认证,Spring Security + JWT(java web token)。
Spring Security 官网介绍
https://spring.io/projects/spring-security

image.png
官网文档说明:
https://docs.spring.io/spring-security/site/docs/5.4.1/reference/html5/
image.png
SpringSecurity是一个强大的可高度定制的认证和授权框架,
对于Spring应用来说它是一套Web安全标准。SpringSecurity注重于为Java应用提供认证和授权功能,
像所有的Spring项目一样,它对自定义需求具有强大的扩展性。

JWT是JSON WEB TOKEN的缩写,它是基于 RFC 7519 标准定义的一种可以安全传输的的JSON对象,
由于使用了数字签名,所以是可信任和安全的。

JWT的组成
JWT token的格式:header.payload.signature
1.header中用于存放签名的生成算法 {"alg": "HS512"}

2.payload中用于存放用户名、token的生成时间和过期时间
{"sub":"admin","created":1489079981393,"exp":1489684781}

3.signature为以header和payload生成的签名,一旦header和payload被篡改,验证将失败
//secret为加密算法的密钥
String signature = HMACSHA512(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)

直接上案例:

gihub 代码地址:https://github.com/LaiHouWen/SpringSecurityJwt

项目借鉴 开源项目 mall商城,http://www.macrozheng.com/#/architect/mall_arch_04,剥离出来的。

先准备一张用户表admin,角色表role,用户权限表permission,用户和角色关系表,用户与角色是多对多关系admin_role_relation,用户角色和权限关系表,角色与权限是多对多关系role_permission_relation,用户和权限关系表admin_permission_relation。

admin表sql

DROP TABLE IF EXISTS `admin`;
CREATE TABLE `admin`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `password` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `email` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮箱',
  `nick_name` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '昵称',
  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
  `login_time` datetime(0) NULL DEFAULT NULL COMMENT '最后登录时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户表' ROW_FORMAT = Dynamic;

role表SQL

DROP TABLE IF EXISTS `role`;
CREATE TABLE `role`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '名称',
  `description` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '描述',
  `admin_count` int(11) NULL DEFAULT NULL COMMENT '后台用户数量',
  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间'
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户角色表' ROW_FORMAT = Dynamic;

permission表sql

DROP TABLE IF EXISTS `permission`;
CREATE TABLE `permission`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `pid` bigint(20) NULL DEFAULT NULL COMMENT '父级权限id',
  `name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '名称',
  `value` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '权限值',
  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间'
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 19 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户权限表' ROW_FORMAT = Dynamic;

admin_permission_relation表sql

DROP TABLE IF EXISTS `admin_permission_relation`;
CREATE TABLE `admin_permission_relation`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `admin_id` bigint(20) NULL DEFAULT NULL,
  `permission_id` bigint(20) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户和权限关系表' ROW_FORMAT = Dynamic;

admin_role_relation表sql

DROP TABLE IF EXISTS `admin_role_relation`;
CREATE TABLE `admin_role_relation`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `admin_id` bigint(20) NULL DEFAULT NULL,
  `role_id` bigint(20) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户和角色关系表' ROW_FORMAT = Dynamic;

role_permission_relation表sql

DROP TABLE IF EXISTS `role_permission_relation`;
CREATE TABLE `role_permission_relation`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `role_id` bigint(20) NULL DEFAULT NULL,
  `permission_id` bigint(20) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 18 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户角色和权限关系表' ROW_FORMAT = Dynamic;
1 . pom导入依赖
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!-- redis -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!--SpringSecurity依赖配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- MyBatis 生成器 -->
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.3.7</version>
        </dependency>
        <!--MyBatis分页插件-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.10</version>
        </dependency>
        <!--集成druid连接池-->
        <!--web监控 http://127.0.0.1:8080/druid/index.html -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!--Mysql数据库驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--Swagger-UI API文档生产工具-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!--Hutool Java工具包-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.4.7</version>
        </dependency>
        <!--JWT(Json Web Token)登录支持-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
        <!--参数校验 javax.validation.constraints-->
        <!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.1.5.Final</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
2. application配置
server:
  port: 8080

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/testmall?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
  redis:
    # redis服务器地址
    host: localhost
    # redis数据库索引(默认为0)
    database: 0
    # redis服务器连接端口
    port: 6379
    # redis 服务器连接密码 默认为空
    password:
    jedis:
      pool:
        # 连接池最大连接数(使用负值表示没有限制)
        max-active: 8
        #  连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
        # 连接池中的最大空闲连接
        max-idle: 8
        # 连接池中的最小空闲连接
        min-idle: 0
    # 连接超时时间(毫秒)
    timeout: 3000ms


# 自定义 redis key
redis:
  # 自定义 redis key
  key:
    prefix:
      authCode: "portal:authCode:"
    expire:
      #验证码超期时间
      authCode: 120

#自定义字段
jwt:
  secret: mySecret
  # jwt超期限时间 60*60*24
  expiration: 604800
  # JWT存储的请求头
  tokenHeader: Authorization
  # JWT负载中拿到开头
  tokenHead: Bearer

#mybatis
mybatis:
  #mapper 映射文件地址
  mapper-locations:
    - classpath:mapper/*.xml
    - classpath:com/**/mapper/*.xml
  1. security 配置
/**
 * SpringSecurity的配置
 *
 * UserDetails:SpringSecurity定义用于封装用户信息的类(主要是用户信息和权限),
 * 需要自行实现;
 */
@Configuration
//开启Security
@EnableWebSecurity
//保证post之前的注解可以使用
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UmsAdminService adminService;
    @Autowired
    private RestfulAccessDeniedHandler restfulAccessDeniedHandler;
    @Autowired
    private RestAuthenticationEntryPoint restAuthenticationEntryPoint;

    /**
     * 用于配置需要拦截的url路径、jwt过滤器及出异常后的处理器;
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf()
                //由于使用的是JWT,我们这里不需要csrf
                .disable()//
                //基于token,所以不需要session
                .sessionManagement()
                //STATELESS不创建httpsession并不使用
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)//
                .and()
                .authorizeRequests()
                //允许对于网站静态资源的无授权访问
                .antMatchers(HttpMethod.GET,
                        "/",
                        "/*.html",
                        "/favicon.ico",
                        "/**/*.html",
                        "/**/*.css",
                        "/**/*.js",
                        "/swagger-resources/**",
                        "/v2/api-docs")
                .permitAll()
                //对登录注册要允许匿名访问
                .antMatchers("/admin/login",
                        "/admin/register")
                .permitAll()
                //跨域请求会先进行一次options请求
                .antMatchers(HttpMethod.OPTIONS)
                .permitAll()
                //测试时全部运行访问
//                .antMatchers("/**")
//                .permitAll()
                //除上面外的所有请求全部需要鉴权认证
                .anyRequest()
                .authenticated();
        //禁用缓存
        http.headers().cacheControl();
        //添加JWT filter 前置拦截
        http.addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
        //添加自定义未授权和未登录结果返回
        http.exceptionHandling().accessDeniedHandler(restfulAccessDeniedHandler)
                .authenticationEntryPoint(restAuthenticationEntryPoint);
    }

    /**
     * 用于配置 UserDetailsService 及PasswordEncoder;
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService())
                .passwordEncoder(passwordEncoder());
    }

    /**
     * SpringSecurity定义的用于对密码进行编码及比对的接口,
     * 目前使用的是BCryptPasswordEncoder;
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    /**
     * SpringSecurity定义的核心接口,用于根据用户名获取用户信息,需要自行实现;
     * @return
     */
    @Bean
    public UserDetailsService userDetailsService(){
        //获取登录用户信息,查询用户权限
//        return username -> {
//            UmsAdmin admin = adminService.getAdminByUsername(username);
//            if (admin !=null ){
//                List<UmsPermission> permissionList = adminService.getPermissionList(admin.getId());
//                return new AdminUserDetails(admin,permissionList);
//            }
//            throw new UsernameNotFoundException("用户名或密码错误");
//        };
        return new UserDetailsServiceImpl();
    }

    /**
     * 在用户名和密码校验前添加的过滤器,
     * 如果有jwt的token,会自行根据token信息进行登录。
     * @return
     */
    @Bean
    public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter(){
        return new JwtAuthenticationTokenFilter();
    }

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

拦截器
JwtAuthenticationTokenFilter

/**
 * JWT登录授权过滤器
 * 在用户名和密码校验前添加的过滤器,如果请求中有jwt的token且有效,
 * 会取出token中的用户名,然后调用SpringSecurity的API进行登录操作。
 * 请求 前置 过滤 token
 */
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    private static final Logger LOGGER =LoggerFactory.getLogger(JwtAuthenticationTokenFilter.class);
    @Autowired
    private UmsAdminService umsAdminService;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Value("${jwt.tokenHeader}")
    private String tokenHeader;
    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        String authHeader = request.getHeader(this.tokenHeader);
        LOGGER.info("checking authHeader:{}",authHeader);
        if (authHeader != null && authHeader.startsWith(this.tokenHead)){
            //The part after "Bearer "
            String authToken = authHeader.substring(this.tokenHead.length());
            LOGGER.info("checking authToken:{}",authToken);
            String username = jwtTokenUtil.getUserNameFromToken(authToken);
            LOGGER.info("checking username:{}",username);
            //SecurityContextHolder.getContext().getAuthentication() == null
            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
               //
                UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);

                if (jwtTokenUtil.validateToken(authToken, userDetails)) {
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    LOGGER.info("authenticated user:{}", username);
                    //打印用户的权限
                    LOGGER.info("authenticated Authorities:{}", userDetails.getAuthorities().size());
                    //这个需要设置
                    //如果没有这个会报 :Full authentication is required to access this resource
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }
        }
        filterChain.doFilter(request,response);
    }

}

RestAuthenticationEntryPoint

/**
 * 当未登录或者token失效访问接口时,自定义的返回结果
 */
@Component
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
    private static final Logger LOGGER = LoggerFactory.getLogger(RestAuthenticationEntryPoint.class);

    @Override
    public void commence(HttpServletRequest request,
                         HttpServletResponse response,
                         AuthenticationException e) throws IOException, ServletException {
        LOGGER.info("RestAuthenticationEntryPoint commence 未登录或者token失效访问接口");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");
        response.getWriter().println(JSONUtil.parse(CommonResult.unauthorized(e.getMessage())));
        response.getWriter().flush();
    }

}

RestfulAccessDeniedHandler

/**
 * 当访问接口没有权限时,自定义的返回结果
 *
 */
@Component
public class RestfulAccessDeniedHandler implements AccessDeniedHandler {
    private static final Logger LOGGER = LoggerFactory.getLogger(RestfulAccessDeniedHandler.class);

    @Override
    public void handle(HttpServletRequest request,
                       HttpServletResponse response,
                       AccessDeniedException e) throws IOException, ServletException {
        LOGGER.info("RestfulAccessDeniedHandler handle 当访问接口没有权限时,自定义的返回结果");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");
        //没有访问权限
        response.getWriter().println(JSONUtil.parse(CommonResult.failed(e.getMessage())));
        response.getWriter().flush();
    }

}

service
UmsAdminService

/**
 *
 */
public interface UmsAdminService {

    //根据用户名获取后台管理员
    UmsAdmin getAdminByUsername(String username);

    //注册功能
    UmsAdmin register(UmsAdmin umsAdminParam);

    /**
     *  登录功能
     * @param username
     * @param password
     * @return 生成的JWT的token
     */
    String login(String username,String password);

    //获取用户所有权限(包括角色权限和+-权限)
    List<UmsPermission> getPermissionList(Long adminId);

}

UmsAdminServiceImpl

/**
 *UmsAdminService实现类
 */
@Service
public class UmsAdminServiceImpl implements UmsAdminService {

    private static final Logger LOGGER = LoggerFactory.getLogger(UmsAdminServiceImpl.class);

    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Autowired
    private UmsAdminMapper adminMapper;

    @Autowired
    private UmsAdminRoleRelationDao adminRoleRelationDao;

    //通过用户名获取管理员信息
    @Override
    public UmsAdmin getAdminByUsername(String username) {
        UmsAdminExample example = new UmsAdminExample();
        example.createCriteria().andUsernameEqualTo(username);
        List<UmsAdmin> adminList = adminMapper.selectByExample(example);
        if (adminList != null && adminList.size()>0){
            return adminList.get(0);
        }
        return null;
    }

    @Override
    public UmsAdmin register(UmsAdmin umsAdminParam) {
        UmsAdmin umsAdmin = new UmsAdmin();
        BeanUtils.copyProperties(umsAdminParam,umsAdmin);
        umsAdmin.setCreateTime(new Date());
        umsAdmin.setStatus(1);
        //查询是否有相同用户名的用户
        UmsAdminExample example = new UmsAdminExample();
        example.createCriteria().andUsernameEqualTo(umsAdmin.getUsername());
        List<UmsAdmin> umsAdminList = adminMapper.selectByExample(example);
        if (umsAdminList.size()>0){
            return null;
        }
        //将密码进行加密操作
        String encodePassword = passwordEncoder.encode(umsAdmin.getPassword());
        umsAdmin.setPassword(encodePassword);
        adminMapper.insert(umsAdmin);
        return umsAdmin;
    }

    @Override
    public String login(String username, String password) {
        String token = null;
        try {
            AdminUserDetails userDetails = null;
            List<UmsPermission> permissionList=null;
            //获取用户的信息
            UmsAdmin admin = getAdminByUsername(username);
            if (admin==null){
                throw new BadCredentialsException("用户不存在");
            }
            permissionList = getPermissionList(admin.getId());
            userDetails = new AdminUserDetails(admin,permissionList);

            if (!passwordEncoder.matches(password,userDetails.getPassword())){
                throw new BadCredentialsException("密码不正确");
            }
            UsernamePasswordAuthenticationToken authenticationToken =
                    new UsernamePasswordAuthenticationToken(userDetails,null,userDetails.getAuthorities());
//            //避免跨多个线程的竞争条件
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            token = jwtTokenUtil.generateToken(admin);

//            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
//            if (!passwordEncoder.matches(password, userDetails.getPassword())) {
//                throw new BadCredentialsException("密码不正确");
//            }
//            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
//            SecurityContextHolder.getContext().setAuthentication(authentication);
//            token = jwtTokenUtil.generateToken(userDetails);

        }catch (AuthenticationException e){
            LOGGER.warn("登录异常:{}",e.getMessage());
        }
        return token;
    }

    @Override
    public List<UmsPermission> getPermissionList(Long id) {
        return adminRoleRelationDao.getPermissionList(id);
    }


}

UserDetailsServiceImpl

/**
 * UserDetailsService 实现 返回权限查询
 */
public class UserDetailsServiceImpl implements UserDetailsService {
    private static final Logger logger = LoggerFactory.getLogger(UserDetailsServiceImpl.class);

    @Autowired
    private UmsAdminService umsAdminService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        UmsAdmin admin = umsAdminService.getAdminByUsername(username);
        if (admin !=null ){
            List<UmsPermission> permissionList = umsAdminService.getPermissionList(admin.getId());
            return new AdminUserDetails(admin,permissionList);
        }
        throw new UsernameNotFoundException("用户名或密码错误");

    }
}

/**
 * 用户与角色管理自定义Dao
 * mapper映射
 */
public interface UmsAdminRoleRelationDao {

    //获取用户所有权限(包括+-权限)
    public List<UmsPermission> getPermissionList(@Param("adminId") Long adminId);

}

UmsAdminRoleRelationDao.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mall.tiny04.dao.UmsAdminRoleRelationDao">

<select id="getPermissionList" resultMap="com.mall.tiny04.mbg.mapper.UmsPermissionMapper.BaseResultMap">
     SELECT
            p.*
        FROM
            admin_role_relation ar
            LEFT JOIN role r ON ar.role_id = r.id
            LEFT JOIN role_permission_relation rp ON r.id = rp.role_id
            LEFT JOIN permission p ON rp.permission_id = p.id
        WHERE
            ar.admin_id = #{adminId}
            AND p.id IS NOT NULL
            AND p.id NOT IN (
                SELECT
                    p.id
                FROM
                    admin_permission_relation pr
                    LEFT JOIN permission p ON pr.permission_id = p.id
                WHERE
                    pr.type = - 1
                    AND pr.admin_id = #{adminId}
            )
        UNION
        SELECT
            p.*
        FROM
            admin_permission_relation pr
            LEFT JOIN permission p ON pr.permission_id = p.id
        WHERE
            pr.type = 1
            AND pr.admin_id = #{adminId}

</select>
</mapper>

controller方法上添加权限



image.png
    @PostMapping("/update/{id}")
    // id 是否有 update权限
    @PreAuthorize("hasPermission(#id,'update')")
    //是否有创建权限
    //@PreAuthorize("hasAuthority('create')") 
    // 是否有admin权限
   // @PreAuthorize("hasRole('admin')")
    @ResponseBody
    public CommonResult updateBrand(@PathVariable("id") Long id,
                                    @RequestBody PmsBrand pmsBrand,
                                    BindingResult result){
    }

相关文章

网友评论

      本文标题:SpringBoot Security JWT 登录授权认证

      本文链接:https://www.haomeiwen.com/subject/snlwiktx.html