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

yizhihongxing

下面来详细讲解如何实现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日

相关文章

  • Vue中util的工具函数实例详解

    Vue中util的工具函数实例详解 在Vue中,utils工具函数是非常重要的一部分。它们能够帮助我们更加方便地进行Vue组件开发,并提高我们的开发效率。本文将详细讲解Vue中util的工具函数种类、使用方法和实例。 Vue中util的工具函数种类 Vue的utils工具函数主要包括以下几种类型: 样式处理相关的工具函数:包括kebabCase、camelC…

    Vue 2023年5月28日
    00
  • Vue中.vue文件比main.js先执行的问题及解决

    在Vue项目中,经常会遇到.vue文件比main.js先执行的问题,并且该问题可能会导致程序运行失败或运行结果异常。下面是解决该问题的完整攻略。 问题描述 在Vue项目的main.js文件中,我们通常使用Vue框架的实例化方法来启动整个应用程序。然而,在某些情况下,我们需要在main.js文件中引入.vue文件,并且在实例化Vue应用程序之前使用该文件中的组…

    Vue 2023年5月28日
    00
  • vue项目打包部署后默认路由不正确的解决方案

    首先,我们需要理解打包过程中的路由问题。在vue项目中,路由由路由表文件(router/index.js)控制,如果不指定默认路由,就会采用默认的路由配置方式,即会访问localhost:8080/#/,但是在部署后,如果直接访问网站地址,就无法正确渲染网页,因为在服务器中,项目的router.base需要指定为网站地址,而不是默认的localhost:80…

    Vue 2023年5月28日
    00
  • Vue echarts画甘特图流程详细讲解

    下面我将详细讲解“Vue echarts画甘特图流程详细讲解”的完整攻略。 1. 甘特图简介 甘特图是一种常用于项目管理的图表类型,用于展示任务的时间轴,显示各个任务的开始时间、结束时间和持续时间。它能够清晰地展示每个任务的进展情况,帮助团队掌握项目进展,及时协调、调整工作计划和资源分配。 2. 准备工作 在使用 Vue 和 echarts 画甘特图之前,我…

    Vue 2023年5月29日
    00
  • VueJS 组件参数名命名与组件属性转化问题

    VueJS 组件能够让我们用单个组件来定义特定状态下的 UI。在组件内部,通常会存在着 props 对象,用于指定组件的外部属性。然而,在指名组件属性的时候,一些参数名可能会被转化成别的名称,这给开发者造成了很多困扰。下面就是完整的攻略,涵盖了参数名命名和属性转换两个方面。 组件参数名命名 Vue 组件参数名的使用一般分为 kebab-case、camelC…

    Vue 2023年5月27日
    00
  • Vue的Props实例配置详解

    Vue的Props实例配置详解 在Vue中,Props是父组件向子组件传递数据的一个重要机制,用于解决组件之间的通信问题。本篇文章将详细讲解Vue中的Props实例配置,希望能对Vue的开发者提供帮助。 什么是Props Props是Vue中一个重要的特性,它是父组件向子组件传递数据的一个机制。可以将Props看作是父组件向子组件传递数据的一个桥梁。 如何定…

    Vue 2023年5月27日
    00
  • java WebSocket客户端断线重连的实现方法

    下面我将为您详细讲解 “java WebSocket客户端断线重连的实现方法” 的完整攻略。 什么是WebSocket客户端断线重连 在WebSocket应用中,客户端与服务器建立的长连接可能会由于网络原因或其他客户端或服务端的错误导致连接中断。如果我们的WebSocket客户端无法及时检测到这种情况并重新建立连接,会导致应用程序无法正常工作。为了解决这个问…

    Vue 2023年5月28日
    00
  • Vue.js 中的 v-model 指令及绑定表单元素的方法

    当使用 Vue.js 开发表单时,经常需要将表单元素的值(如文本输入框、单选框、复选框等)与 Vue 组件中的数据进行绑定,这就需要用到 Vue.js 中的 v-model 指令了。下面是具体的操作方法: 绑定文本输入框的值 将文本输入框的值与 Vue 组件中的 data 属性进行双向绑定的方法,示例如下: 在 Vue 组件的 template 中,定义一个…

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