SpringBoot+Shiro+Jedis+JWT+基于url的权限拦截系统

本文介绍了如何使用SpringBoot、Shiro、Jedis和JWT构建一个基于URL的权限拦截系统。选择SpringBoot+Shiro是因为其简洁的结构和较低的学习成本。系统设计中,登录成功后返回JWT令牌,前端保存并在后续请求中携带。自定义拦截器处理请求,通过JWT进行身份和权限验证,并利用Redis存储和刷新JWT。当JWT验证失败时,将重定向至登录页面。
摘要由CSDN通过智能技术生成

在众多的开发任务里,权限管理系统开发是常见的也是大部分程序员并着手开发过的系统。在最近的任务,上级要求开发一个通用的基于url的权限控制系统,由于笔者对shiro早有接触,虽然springsecurity的功能强大,与spring易整合但结构复杂组件较多,为了在有限的开发周期内减少学习成本,最后确定技术选型:springboot+shiro+redis+jwt+mybatis+mysql

设计思路

在这里插入图片描述

  • shiro配置放行uri,比如登录登出等游客身份也能调用的接口等资源,登陆成功的用户服务器会返回特有的jwt(作为令牌)给前端交由前台保存,可保存到localStorage或sessionStorage,之后该用户的请求的header都需带上jwt
  • 因为是基于url的拦截,新建拦截器继承BasicHttpAuthenticationFilter,重写preHadle(),isAccessAllowed().onAccessDenied()方法,主要功能:捕获请求,获取请求头的token进行身份验证,获取请求uri进行权限认证,认证通过才能调用controller接口
  • 自定义realm类重写doGetAuthenticationInfo(),doGetAuthorizationInfo()方法,自定义身份认证及权限认证方式,给上面的拦截器所调用
  • 生成的jwt会保存到redis交由redis维护,以用户名为key,过期时间30分钟,每次请求经过拦截器时候会刷新过期时间,若reidis获取不到jwt或jwt与请求头的jwt不一致则认证失败返回登陆页重新登陆

上菜

导包(展示部分)

        <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>3.0.7.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-support -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-support</artifactId>
            <version>2.3.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.0.7.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->

        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.55</version>
        </dependency>
        
        <!-- JWT:Json Web Token 配置 用于请求身份验证 -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>${
   jjwt.version}</version>
        </dependency>

        <!-- Shiro -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>${
   shiro.version}</version>
        </dependency>

        <!-- Redis-Jedis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>${
   jedis.version}</version>
        </dependency>

    </dependencies>

配置Jedis

package com.rq.authority.config.redis;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * Jedis配置,项目启动注入JedisPool
 */
@Configuration
@EnableAutoConfiguration
public class JedisConfig {
   

    /**
     * LOGGER
     */
    private static final Logger logger = LoggerFactory.getLogger(JedisConfig.class);

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Value("${spring.redis.password}")
    private String password;

    @Value("${spring.redis.timeout}")
    private int timeout;

    @Value("200")
    private int maxActive;

    @Value("-1")
    private int maxWait;

    @Value("8")
    private int maxIdle;

    @Value("0")
    private int minIdle;

    @Bean
    public JedisPool redisPoolFactory(){
   
        try {
   
            JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
            jedisPoolConfig.setMaxIdle(maxIdle);
            jedisPoolConfig.setMaxWaitMillis(maxWait);
            jedisPoolConfig.setMaxTotal(maxActive);
            jedisPoolConfig.setMinIdle(minIdle);
            JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password);
            logger.info("初始化Redis连接池JedisPool成功!地址: " + host + ":" + port);
            return jedisPool;
        } catch (Exception e) {
   
            logger.error("初始化Redis连接池JedisPool异常:" + e.getMessage());
        }
        return null;
    }

    public String getHost() {
   
        return host;
    }

    public void setHost(String host) {
   
        this.host = host;
    }

    public int getPort() {
   
        return port;
    }

    public void setPort(int port) {
   
        this.port = port;
    }

    public String getPassword() {
   
        return password;
    }

    public void setPassword(String password) {
   
        this.password = password;
    }

    public int getTimeout() {
   
        return timeout;
    }

    public void setTimeout(int timeout) {
   
        this.timeout = timeout;
    }

    public int getMaxActive() {
   
        return maxActive;
    }

    public void setMaxActive(int maxActive) {
   
        this.maxActive = maxActive;
    }

    public int getMaxWait() {
   
        return maxWait;
    }

    public void setMaxWait(int maxWait) {
   
        this.maxWait = maxWait;
    }

    public int getMaxIdle() {
   
        return maxIdle;
    }

    public void setMaxIdle(int maxIdle) {
   
        this.maxIdle = maxIdle;
    }

    public int getMinIdle() {
   
        return minIdle;
    }

    public void setMinIdle(int minIdle) {
   
        this.minIdle 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值