Spring Boot Shiro 在 Web 应用中的作用详解
简介
Shiro 是一个用于 Java 应用的轻量级安全框架,提供了认证、授权、加密以及会话管理等功能,可以方便地集成进 Spring Boot 项目中使用和配置。本文将详细介绍在 Web 应用中使用 Spring Boot Shiro 的过程和作用。
步骤
1. 添加依赖项
在 pom.xml 文件中添加如下依赖项,Spring Boot Shiro 就被引入到项目中了。
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.6.0</version>
</dependency>
2. 编写 Shiro 配置
在 Spring Boot 项目中,我们可以使用 @Configuration 注解为 Shiro 提供配置信息。
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
filterFactoryBean.setSecurityManager(securityManager);
filterFactoryBean.setLoginUrl("/login");
filterFactoryBean.setSuccessUrl("/index");
filterFactoryBean.setUnauthorizedUrl("/error");
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/", "anon");
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/static/**", "anon");
filterChainDefinitionMap.put("/**", "authc");
filterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return filterFactoryBean;
}
@Bean
public DefaultWebSecurityManager securityManager(Realm realm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realm);
return securityManager;
}
@Bean
public Realm realm() {
return new MyRealm();
}
}
ShiroFilterFactoryBean 用于创建 ShiroFilter 的工厂类,用以配置 Shiro 过滤器链。DefaultWebSecurityManager 是整个 Shiro 架构的核心,负责管理 Subject、Realm 和 Session 等。Realm 则会完成登陆认证和权限校验。
3. 编写自定义 Realm
Realm 用于实现具体的认证和授权逻辑。
public class MyRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
// 从数据库或者缓存中获取用户的角色和权限信息,并赋值给 authorizationInfo
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
String username = usernamePasswordToken.getUsername();
// 从数据库中获取用户名对应的密码,然后返回一个 AuthenticationInfo 实例
return new SimpleAuthenticationInfo(username, "password", getName());
}
}
在 doGetAuthorizationInfo 方法中,我们可以从数据库或者缓存中获取用户的角色和权限信息,并通过 SimpleAuthorizationInfo 类赋值给 authorizationInfo 对象。在 doGetAuthenticationInfo 方法中,我们可以根据用户名密码查询数据库,返回一个 AuthenticationInfo 实例,用于 Shiro 的认证。
4. 在 Controller 中应用 Shiro
在项目中的 Controller 中,可以通过注解的方式实现对请求的权限控制。
@Controller
public class UserController {
@RequestMapping("/user")
@RequiresPermissions("user:list")
public String getUserList() {
// 权限校验成功,返回用户列表页面
return "userList";
}
}
注解 @RequiresPermissions 可以用于详细控制用户对某个请求是否具有访问权限。在本例中,当用户拥有 user:list 权限时,才能访问 /user 请求。
5. 编写登录页面
在登录页面中,我们可以使用 Shiro 提供的默认标签库,如 ShiroLackTag、ShiroPrincipalTag、ShiroPermissionTag 等。
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<div class="container">
<div class="card card-login mx-auto text-center">
<div class="card-header">登 录</div>
<div class="card-body">
<form method="post" action="/login">
<div class="form-group">
<input type="text" class="form-control" name="username" placeholder="请输入用户名">
<input type="password" class="form-control" name="password" placeholder="请输入密码">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-block">登录</button>
</div>
</form>
<div class="text-right">没有账号?<a href="#">注册</a></div>
<hr>
<a href="#">忘记密码</a>
<br>
<shiro:hasRole name="admin">
<a href="#">管理中心</a>
</shiro:hasRole>
</div>
</div>
</div>
在本例中,我们使用了 Shiro 的 hasRole 标签,用于判断用户是否具有 admin 角色,并显示相应的链接。
示例
示例1:控制用户访问权限
假设我们要开发一个基于 Spring Boot 的博客系统,其中需要对用户的访问权限进行控制。如管理员可对博客进行管理、撰写和编辑,普通用户只能对博客进行浏览和评论等操作。
我们可以使用 Shiro 实现这样的控制,通过在 Controller 中使用 @RequiresPermissions 注解来标记用户对某个请求的访问权限,并在 MyRealm 的 doGetAuthorizationInfo 方法中获取用户的角色信息,再根据角色信息来判断用户是否有权限访问请求。
示例2:实现单点登录
假设我们有多个子系统,用户只需要在一个子系统中登录,就可以在其他子系统中进行访问操作,即实现了单点登录。为了保护用户信息的安全,我们采用 Shiro 进行身份认证和权限校验。
我们可以在每个子系统中都引入 Spring Boot Shiro,然后在每个子系统中配置相同的 Realm,这样用户在登录第一个子系统时,就会在 Realm 中记录下用户的身份信息和权限信息。当用户在访问其他子系统时,只需要通过 Shiro 的 Subject.doAuthenticate() 方法进行认证即可,无需再次输入用户名密码,实现了单点登录。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Boot Shiro在Web应用中的作用详解 - Python技术站