Spring Boot2.x 整合 Shiro(JWT模式)

烟雨江南 2024-03-09 ⋅ 67 阅读

Spring Boot2.x 整合 Shiro(JWT模式)

在开发Web应用程序时,安全性是非常重要的一方面。Shiro是一个优秀的Java安全框架,可以为我们的应用程序提供诸多安全功能。与此同时,Spring Boot是现代化的Java开发框架,大大简化了Spring应用程序的开发和部署过程。

本文将介绍如何使用Spring Boot来整合Shiro,并使用JWT(JSON Web Token)模式来管理用户身份验证和授权。

1. 引入依赖

首先,我们需要添加Spring Boot和Shiro的相关依赖。在pom.xml文件中添加以下依赖项:

<!-- Spring Boot -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Shiro -->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring-boot-starter</artifactId>
    <version>1.7.1</version>
</dependency>

2. 配置Shiro

在Spring Boot项目的配置文件中,我们需要添加Shiro的相关配置项。创建一个application.properties文件,并添加以下配置:

# Shiro
shiro:
  anon-urls: /api/login
  jwt:
    secret: your-secret-key
    expiration: 86400 # 设置JWT的过期时间为24小时

在这个示例中,我们配置了一个匿名URL(即无需身份验证即可访问的URL),以及JWT密钥和过期时间。

3. 创建Shiro过滤器

接下来,我们需要创建一个Shiro过滤器,并配置URL的权限访问规则。在Spring Boot中,可以通过编写一个ShiroConfig类来实现,如下所示:

@Configuration
public class ShiroConfig {

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

    @Bean
    public MyRealm realm() {
        return new MyRealm();
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
        filter.setSecurityManager(securityManager);
        filter.setLoginUrl("/api/login");
        filter.setUnauthorizedUrl("/api/unauthorized");

        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();

        // 匿名访问的URL
        filterChainDefinitionMap.put("/api/login", "anon");

        // 需要认证的URL
        filterChainDefinitionMap.put("/api/**", "jwt");

        filter.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return filter;
    }
}

在这个示例中,我们创建了一个自定义的MyRealm类来处理用户身份验证和授权。我们还配置了Shiro过滤器并设置了匿名URL和需要认证的URL。

4. 编写自定义Realm

创建一个MyRealm类,继承自AuthorizingRealm,并实现其中的方法。

public class MyRealm extends AuthorizingRealm {

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // TODO: 实现授权逻辑
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // TODO: 实现身份验证逻辑
        return null;
    }
}

在这个示例中,我们需要实现doGetAuthorizationInfo方法来处理用户权限授权逻辑,并实现doGetAuthenticationInfo方法来处理用户身份验证逻辑。

5. 实现身份验证和授权逻辑

MyRealm类中,我们可以使用Spring Data JPA或其他数据访问技术来查询数据库并验证用户的身份和权限。

以下是一个示例代码,使用Spring Data JPA查询数据库中的用户信息:

@Autowired
private UserRepository userRepository;

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    String username = (String) token.getPrincipal();
    User user = userRepository.findByUsername(username);

    if (user == null) {
        throw new UnknownAccountException("Unknown account: " + username);
    }

    return new SimpleAuthenticationInfo(username, user.getPassword(), getName());
}

通过覆盖doGetAuthorizationInfo方法,我们可以进行用户权限的授权逻辑。例如,我们可以根据用户角色来设置权限:

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    String username = (String) principals.getPrimaryPrincipal();
    User user = userRepository.findByUsername(username);

    SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

    List<String> roles = user.getRoles();
    authorizationInfo.addRoles(roles);

    // TODO: 添加更多授权逻辑

    return authorizationInfo;
}

6. JWT身份验证

在上述示例中,我们使用JWT来管理用户的身份验证。JWT是一个开放标准,定义了一种紧凑且自包含的方式来在各方之间安全传输信息。它使用签名保证了信息的完整性和真实性。

在Shiro中,我们可以使用JwtFilter类来解析和验证JWT令牌。添加以下代码来使用该过滤器:

@Bean
public JwtFilter jwtFilter() {
    return new JwtFilter();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.addFilterBefore(jwtFilter(), UsernamePasswordAuthenticationFilter.class);
}

总结

通过整合Spring Boot和Shiro,我们可以轻松地实现用户身份验证和授权的功能。使用JWT令牌可以提供更高的安全性和可扩展性。希望本文对你了解如何整合Spring Boot和Shiro有所帮助。

参考链接:


全部评论: 0

    我有话说: