Bootstrap

Spring Boot集成Shiro授权

在现代Web应用程序开发中,安全性是一个至关重要的方面。Shiro是一个强大的Java安全框架,提供了身份验证、授权、密码存储和会话管理等功能。本文将详细介绍如何在Spring Boot项目中集成Shiro,以实现授权功能。

一、项目准备

首先,我们需要创建一个Spring Boot项目。你可以使用Spring Initializr或者你喜欢的IDE(如IntelliJ IDEA)来创建一个新的Spring Boot项目。

二、添加Maven依赖

pom.xml文件中添加Shiro相关的依赖。这里有两种方式:

  1. 使用shiro-spring依赖:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
  1. 使用shiro-spring-boot-web-starter依赖(更简便):
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.4.2</version>
</dependency>
三、配置Shiro

在Spring Boot项目中,我们通常使用application.ymlapplication.properties文件来配置Shiro。以下是一个简单的application.yml配置示例:

spring:
profiles:
active: dev
mybatis:
mapper-locations: classpath:mapper/*Mapper.xml
server:
port: 8080
shiro:
web:
enabled: true
loginUrl: /login
四、创建Shiro配置类

Shiro配置类用于配置Shiro的SecurityManager和自定义的Realm。以下是一个示例:

import org.apache.shiro.mgt.DefaultWebSecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.DefaultWebSubjectFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
@Bean
public UserRealm userRealm() {
return new UserRealm();
}
@Bean
public DefaultWebSecurityManager securityManager(UserRealm userRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm);
securityManager.setSubjectFactory(new DefaultWebSubjectFactory());
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/doLogin", "anon");
filterChainDefinitionMap.put("/admin/**", "authc, roles[admin]");
filterChainDefinitionMap.put("/docs/**", "authc, perms[document:read]");
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
}
五、创建自定义Realm

自定义Realm用于处理身份验证和授权逻辑。以下是一个示例:

import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
public class UserRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
String username = (String) principalCollection.getPrimaryPrincipal();
User user = userService.findByUsername(username);
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.setRoles(user.getRoles());
authorizationInfo.setStringPermissions(user.getPermissions());
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
String username = token.getUsername();
User user = userService.findByUsername(username);
if (user == null) {
throw new UnknownAccountException("用户不存在");
}
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
username,
user.getPassword(),
getName()
);
return authenticationInfo;
}
}
六、实现授权功能

在自定义Realm中,我们已经实现了授权逻辑。现在,我们需要在控制器中使用Shiro的注解来实现授权控制。

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/admin")
public class AdminController {
@GetMapping("/dashboard")
@RequiresRoles("admin")
public String dashboard() {
return "Admin Dashboard";
}
@GetMapping("/docs")
@RequiresPermissions("document:read")
public String docs() {
return "Documents";
}
}
七、测试授权功能

启动Spring Boot应用程序,并访问不同的URL来测试授权功能。例如:

  • 访问/admin/dashboard,应该要求登录,并且只有具有admin角色的用户才能访问。
  • 访问/docs,应该要求登录,并且只有具有document:read权限的用户才能访问。
八、总结

通过本文,我们详细介绍了如何在Spring Boot项目中集成Shiro并实现授权功能。Shiro提供了强大的安全功能,可以大大提高Web应用程序的安全性。希望本文对你有所帮助,如果你有任何问题或建议,请随时留言。

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;