Springboot实现Shiro整合JWT的示例代码

下面来详细讲解如何实现Spring Boot整合Shiro和JWT的示例代码。

简介

Shiro是一个强大的安全框架,提供了多种安全特性,例如:认证、授权、加密等等。JWT是一种轻量级的认证机制,它可以使用JSON格式存储用户信息,并且可以在客户端和服务端之间传递。

本文将介绍如何通过Spring Boot实现Shiro整合JWT的示例代码。

示例1:环境搭建

首先,我们需要搭建Spring Boot的环境,具体步骤如下:

  1. 首先,需要安装Java环境,可参考官网文档下载并安装。

  2. 下载并安装Maven,可根据官网文档进行安装。

  3. 创建Spring Boot项目,可使用Spring Initializr进行创建。

  4. 在pom.xml文件中添加Shiro和JWT的依赖项,具体依赖项可参考如下代码块:

```xml

org.apache.shiro
shiro-spring
1.7.1


io.jsonwebtoken
jjwt
0.9.1

```

  1. 配置application.yml文件,具体配置可参考如下代码块:

```yml
# 数据库配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: root

# JWT配置
jwt:
secret: 123456
expireTime: 1800

# Shiro配置
shiro:
filterChainDefinitions: /login = anon\n/** = authc
loginUrl: /login
```

  1. 在WebMvcConfigurer中配置ShiroFilterFactoryBean,具体代码可参考如下代码块:

```java
@Configuration
public class ShiroConfig {

   @Autowired
   private Environment env;

   @Bean
   public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
       ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
       shiroFilterFactoryBean.setSecurityManager(securityManager);
       shiroFilterFactoryBean.setLoginUrl(env.getProperty("shiro.loginUrl"));

       Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
       filterChainDefinitionMap.put("/logout", "logout");
       filterChainDefinitionMap.putAll(parseFilterChainDefinitions(env.getProperty("shiro.filterChainDefinitions")));
       shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

       return shiroFilterFactoryBean;
   }

   @Bean
   public SecurityManager securityManager(Realm realm) {
       DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
       securityManager.setRealm(realm);
       return securityManager;
   }

   @Bean
   public Realm realm() {
       JwtRealm realm = new JwtRealm();
       realm.setCredentialsMatcher(new JwtMatcher());
       return realm;
   }

   private Map<String, String> parseFilterChainDefinitions(String definitions) {
       Map<String, String> chains = new HashMap<>();
       if (StringUtils.isBlank(definitions)) {
           return chains;
       }
       String[] definitionArray = definitions.split("\\n");
       for (String definition : definitionArray) {
           String[] tmp = definition.split("=");
           if (tmp.length == 2) {
               chains.put(tmp[0].trim(), tmp[1].trim());
           }
       }
       return chains;
   }

}
```

  1. 接下来就可以开始编写业务逻辑代码了。

示例2:JWT认证

首先,我们来看一下如何使用JWT实现认证。

  1. 首先,在Shiro的Realm中实现认证逻辑,具体代码可参考如下:

```java
public class JwtRealm extends AuthorizingRealm {

   @Override
   public boolean supports(AuthenticationToken token) {
       return token instanceof JwtToken;
   }

   @Override
   protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
       return null;
   }

   @Override
   protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
       JwtToken jwtToken = (JwtToken) token;
       Claims claims = jwtToken.getClaims();
       Date expireDate = claims.getExpiration();
       if (expireDate.before(new Date())) {
           throw new AuthenticationException("Token expired");
       }
       String username = claims.getSubject();

       return new SimpleAuthenticationInfo(username, token.getCredentials(), getName());
   }

}
```

  1. 接下来,编写JWT工具类,具体代码可参考如下:

```java
public class JwtUtil {

   private static final String secret = "123456";

   public static String createToken(String subject, Date expireTime) {
       SignatureAlgorithm algorithm = SignatureAlgorithm.HS256;
       Date nowDate = new Date();
       byte[] secretBytes = DatatypeConverter.parseBase64Binary(secret);
       JwtBuilder builder = Jwts.builder().setId(UUID.randomUUID().toString())
               .setIssuedAt(nowDate)
               .setSubject(subject)
               .setExpiration(expireTime)
               .signWith(algorithm, secretBytes);
       return builder.compact();
   }

   public static Claims parseToken(String token) {
       try {
           Claims claims = Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary(secret)).parseClaimsJws(token).getBody();
           return claims;
       } catch (JwtException e) {
           return null;
       }
   }

}
```

  1. 最后,在Controller中编写登录接口,具体代码可参考如下:

```java
@RestController
public class AuthController {

   @Value("${jwt.expireTime}")
   private Long expireTime;

   @PostMapping("/login")
   public String login(@RequestParam("username") String username,
                       @RequestParam("password") String password) {

       Subject subject = SecurityUtils.getSubject();
       UsernamePasswordToken token = new UsernamePasswordToken(username, password);
       try {
           subject.login(token);
           String jwtToken = JwtUtil.createToken(username, new Date(System.currentTimeMillis() + expireTime * 1000));
           return jwtToken;
       } catch (AuthenticationException e) {
           return "login error";
       }
   }

}
```

通过以上步骤,就可以实现使用JWT进行认证了。

总结

本文通过示例介绍了如何通过Spring Boot实现Shiro整合JWT的示例代码,其中包括环境搭建、JWT认证等步骤,希望对大家有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Springboot实现Shiro整合JWT的示例代码 - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • 爬虫代理的cookie如何生成运行

    如果使用爬虫代理访问需要登录的网站,必须要使用相应的登录凭证来进行访问。其中,cookie是一种常见的登录凭证。通过设置正确的cookie,可以模拟已登录的状态进行网站访问。下面是一个关于如何在使用爬虫代理时生成cookie的攻略。 步骤一:获取登录凭证 要生成cookie,首先需要获取正确的登录凭证,例如用户名和密码。其中,这些凭证可能需要从数据库或者文件…

    Vue 2023年5月28日
    00
  • vue+elementUI(el-upload)图片压缩,默认同比例压缩操作

    首先需要明确的是,针对 vue+elementUI(el-upload) 图片压缩的操作,实际上是对于上传的图片进行处理,通过 JS 将图片进行压缩,最终实现 web 应用中图片大小的限制。 接下来,我们将分别从以下三个方面对此进行详细讲解: 图片选择与压缩 解决压缩后图片失去原有宽高比例的问题 示例说明 1. 图片选择与压缩 我们可以通过 elementU…

    Vue 2023年5月28日
    00
  • vuex进阶知识点巩固

    关于 “vuex进阶知识点巩固” 的完整攻略,我将按照以下几个方面进行详细讲解: Vuex的基本概念 Vuex的核心概念 Vuex的高级应用 1. Vuex的基本概念 1.1 什么是Vuex? Vuex是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,将组件的共享状态抽取出来,以一个全局单例模式管理。 1.2 V…

    Vue 2023年5月28日
    00
  • vue实现导航栏效果(选中状态刷新不消失)

    Vue实现导航栏效果,一般情况下会根据当前路由的路径来判断当前页面是否高亮选中,但是在刷新页面后,状态会丢失。下面是实现选中状态刷新不消失的完整攻略。 步骤一:路由配置 首先,需要定义好路由配置,这里以vue-router为例。 import Vue from ‘vue’ import VueRouter from ‘vue-router’ Vue.use(…

    Vue 2023年5月29日
    00
  • TypeScript 引用资源文件后提示找不到的异常处理技巧

    TypeScript 是一种强类型的 JavaScript 超集语言。在使用 TypeSript 进行开发时,我们有时会遇到引用资源文件后提示找不到的异常,这通常是因为在 TypeScript 中默认只会编译 .ts 文件,并不会编译其他类型的资源文件(比如 .json 或者 .png 文件)导致的。针对这种问题,我们可以使用以下技巧进行处理。 技巧一:使用…

    Vue 2023年5月28日
    00
  • Vue 实现双向绑定的四种方法

    当我们用Vue框架去编写一个前端应用时,往往需要实现双向绑定,这是Vue框架最重要的特性之一。Vue实现双向绑定的方式有很多,下面将详细讲解四种方法的具体实现过程和示例。 1. Object.defineProperty Object.defineProperty是一种实现双向绑定的最基础的方法,这种方法适用于所有支持ECMAScript5的浏览器。 实现双…

    Vue 2023年5月28日
    00
  • 使用vue编写一个点击数字计时小游戏

    让我详细讲解如何使用Vue来编写一个点击数字计时小游戏。 1. 创建项目并安装依赖 首先,需要在本地电脑上安装Node.js和npm。然后,在命令行中输入以下命令,创建Vue项目: vue create click-number-game 这个命令会创建一个名为“click-number-game”的Vue项目。等待命令行安装完依赖后,进入项目目录: cd …

    Vue 2023年5月29日
    00
  • vue2.x双向数据绑定原理解析

    vue2.x双向数据绑定原理解析 什么是双向数据绑定 双向数据绑定是指视图层和数据层之间的数据同步。当数据层中的数据发生变化时,视图层会自动更新;反之,当视图层中用户操作修改了数据时,数据层的数据也会自动更新。 通常而言,双向数据绑定有两种方式,一种是脏值检测(angular.js),另一种则是数据劫持(vue.js)。 本文将介绍 vue2.x 中的数据劫…

    Vue 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部