本文将介绍shiro的springboot集成,基于官网的指南来做的。虽然比较简单,但还是注意一下版本的兼容性问题。
官网指南:https://shiro.apache.org/spring-boot.html
1 引入shiro
本demo使用springboot 2.2.6.RELEASE,shiro 则选择了 1.12.0。
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.12.0</version>
</dependency>
PS:
shiro 的 1.12.0 版本可能无法支持 springboot 3.X 版本(比如:3.1.2)。
其一是因为新版本 AutoConfigurationExcludeFilter 中改成了对 @AutoConfiguration 注解扫描,导致无法正常自动配置。 从 shiro-spring-boot-web-starter 包的 spring.factory 文件中还是用的 EnableAutoConfiguration 注解来进行自动配置。
2 提供一个Realm的实现
be like:
@Bean
public Realm realm(){
SimpleAccountRealm accountRealm = new SimpleAccountRealm();
accountRealm.addAccount("admin", "12345", ADMIN, USER);
accountRealm.addAccount("user", "12345", USER);
return accountRealm;
}
从上面这个简单的实现,不难看出 Realm 的实现类就是提供用来登录认证的账户信息的。
Realm 有多个实现类,可以挑选合适的,并继承它来做自定义的实现。
可以通过继承 AuthorizingRealm 类来做:
public class AccountRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
@Autowired
private UserRoleService userRoleService;
// 从基础数据存储中检索给定主体的授权信息。从此方法返回实例时,您可能需要考虑使用 SimpleAuthorizationInformation 的实例,因为它适用于大多数情况。
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
...
}
// 从特定于实现的数据源(RDBMS、LDAP 等)中检索给定身份验证令牌的身份验证数据。
// 对于大多数数据源,这意味着只需为关联的主体/用户“提取”身份验证数据,仅此而已,其余的让 Shiro 完成。但是在某些系统中,除了检索数据之外,这种方法实际上还可以执行特定于 EIS 的登录逻辑 - 这取决于 Realm 的实现。
// null 返回值表示任何帐户都不能与指定的令牌关联。
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
...
}
}
3 提供一个 ShiroFilterChainDefinition
为了校验不同的请求路径要求的不同权限,需要用 ShiroFilterChainDefinition 类来定义好(映射)应用中任何特定的请求路径(path)的权限要求。
3.1 直接定义路径的角色&权限校验
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
// logged in users with the 'admin' role
// 要求登录用户有 admin 角色的路径
chainDefinition.addPathDefinition("/admin/**", "authc, roles[admin]");
// logged in users with the 'document:read' permission
// 要求登录用户有 document:read 这个权限的路径
chainDefinition.addPathDefinition("/docs/**", "authc, perms[document:read]");
// all other paths require a logged in user
// 其它所有路径都要求用户要登录
chainDefinition.addPathDefinition("/**", "authc");
return chainDefinition;
}
3.2 通过 shiro 注解
@RequiresPermissions--权限要求注解:
@RequiresPermissions("document:read")
public void readDocument() {
...
}
@RequiresRoles--角色要求注解:
@Controller
public class AccountInfoController {
@RequiresRoles("admin")
@RequestMapping("/admin/config")
public String adminConfig(Model model) {
return "view";
}
}
@RequiresPermissions 和 @RequiresRoles 这两个注解即可以加在方法上面,也可以直接加到类上面。
此外,ShiroFilterChainDefinition 这个bean对象还是需要的:
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
chainDefinition.addPathDefinition("/**", "anon"); // all paths are managed via annotations【所有路径都通过注解进行管理】
// or allow basic authentication, but NOT require it.【或允许基本身份验证,但不需要它】
// chainDefinition.addPathDefinition("/**", "authcBasic[permissive]");
return chainDefinition;
}
4 缓存管理器 CacheManager
需要启用自定义的缓存,那只需要提供一个缓存管理器的bean:
@Bean
protected CacheManager cacheManager() {
return new MemoryConstrainedCacheManager();
}
如果要用 EhCache 或者 redis 等等,需要引用对应的 jar 包依赖,be like:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>${shiro}</version>
</dependency>
@Bean
public CacheManager shiroCacheManager(net.sf.ehcache.CacheManager cacheManager) {
EhCacheManager ehCacheManager = new EhCacheManager();
ehCacheManager.setCacheManager(cacheManager);
return ehCacheManager;
}
5 常见配置
Key | Default Value | Description |
---|---|---|
shiro.enabled | true | 开启shiro的spring模块 |
shiro.web.enabled | true | 开启shiro的spring web模块 |
shiro.annotations.enabled | true | 开启spring支持shiro注解 |
shiro.userNativeSessionManager | false | 如果启用,Shiro将管理HTTP会话而不是容器 |
shiro.sessionManager.cookie.name | JSESSIONID | Session cookie 的名称 |
shiro.sessionManager.cookie.maxAge | -1 | Session cookie 的最大年龄 |
shiro.rememberMeManager.cookie.name | rememberMe | RememberMe cookie 的名称 |
shiro.rememberMeManager.cookie.maxAge | one year | RememberMe cookie 的最大年龄 |
shiro.loginUrl | /login.jsp | 登录页 |
shiro.successUrl | / | 用户登录后的默认登录页面(如果在当前会话中找不到替代页面) |
shiro.unauthorizedUrl | null | 如果用户未经授权,则重定向到的页面(403页面) |
小结:
- 引入jar包依赖
- 提供一个Realm接口的实现--认证用的
- 提供 ShiroFilterChainDefinition 定义--对路径管控的定义
- 缓存管理器--用户登录信息的保存
springboot 3.x 自动配置类的扫描
与 spring.factories 的方式类似,需要在 META-INF
目录下创建 spring
目录,在里面创建一个文件名为: org.springframework.boot.autoconfigure.AutoConfiguration.imports
在文件内直接配置上要相关的配置类,be like:
org.apache.shiro.spring.boot.autoconfigure.ShiroBeanAutoConfiguration
org.apache.shiro.spring.boot.autoconfigure.ShiroAutoConfiguration
org.apache.shiro.spring.boot.autoconfigure.ShiroAnnotationProcessorAutoConfiguration
【由于shiro目前最新版本1.12.0
并不支持springboot 3.x,所以自动配置这块还得自己来。此外,还是由于兼容性问题,最后我没有在项目中升级到shiro最新版本,而是继续使用目前的 1.4.0 版本(能平稳运行。。。)】
注意:本文归作者所有,未经作者允许,不得转载