下面就为您讲解“SpringBoot集成Shiro权限管理简单实现”的详细攻略。
一、配置
1.1 引入依赖
在Maven或Gradle中引入Shiro和SpringBoot的相关依赖:
Maven:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.7.1</version> <!-- 版本可根据实际情况进行调整 -->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Gradle:
implementation 'org.apache.shiro:shiro-web:1.7.1' // 版本可根据实际情况进行调整
implementation 'org.springframework.boot:spring-boot-starter-web'
1.2 配置Shiro
在SpringBoot中使用Shiro,我们需要在配置类(通常是Application.java)中添加一个ShiroFilterFactoryBean和一个DefaultWebSecurityManager的Bean。
示例代码:
@Configuration
public class Application {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean() {
//创建shiroFilterFactoryBean 实例
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//设置SecurityManager
shiroFilterFactoryBean.setSecurityManager(securityManager());
//设置登录页面地址
shiroFilterFactoryBean.setLoginUrl("/login");
//设置无权限路径
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
// 拦截器.
Map<String, String> map = new HashMap<String, String>();
// 配置不会被拦截的链接 顺序判断
//anon:所有url都可以匿名访问
map.put("/login", "anon");
map.put("/static/**", "anon"); //静态资源不拦截
map.put("/**", "authc"); //其他链接必须认证后才能访问
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}
@Bean
public DefaultWebSecurityManager securityManager() {
//创建securityManager实例
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//设置realm
securityManager.setRealm(myShiroRealm());
return securityManager;
}
/**
* 自定义realm
*/
@Bean
public MyShiroRealm myShiroRealm() {
//创建realm实例
MyShiroRealm myShiroRealm = new MyShiroRealm();
return myShiroRealm;
}
}
1.3 配置Realm
自定义的Realm需要继承org.apache.shiro.realm.AuthorizingRealm类,实现其中的protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals)和protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)方法,完成授权和身份认证的逻辑。
示例代码:
public class MyShiroRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//授权逻辑
//获取当前用户
User user = (User) principals.getPrimaryPrincipal();
//创建授权对象
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
//向授权对象中添加角色和权限
authorizationInfo.addRoles(user.getRoles());
authorizationInfo.addStringPermissions(user.getPermissions());
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//身份认证逻辑
//获取用户输入的账号和密码
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
String username = usernamePasswordToken.getUsername();
String password = new String(usernamePasswordToken.getPassword());
//根据用户名查找数据库中的用户对象
User user = userService.findByUsername(username);
if (user == null) {
throw new UnknownAccountException(); //账号不存在
}
if (!password.equals(user.getPassword())) {
throw new IncorrectCredentialsException(); //密码错误
}
//创建身份认证对象
return new SimpleAuthenticationInfo(user, password, getName());
}
}
二、使用
2.1 创建用户实体类
public class User implements Serializable {
private Integer id;
private String username;
private String password;
private List<String> roles;
private List<String> permissions;
//省略getter和setter方法
}
2.2 设计登录页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<h1>登录</h1>
<form action="/login" method="post">
<p>用户名: <input type="text" name="username"></p>
<p>密码: <input type="password" name="password"></p>
<p><input type="submit" value="登录"></p>
</form>
</body>
</html>
2.3 创建根据用户名查询用户的服务接口和实现类
public interface UserService {
User findByUsername(String username);
}
@Service
public class UserServiceImpl implements UserService {
@Override
public User findByUsername(String username) {
//模拟从数据库中查询用户
if ("admin".equals(username)) {
User user = new User();
user.setUsername("admin");
user.setPassword("123456");
user.setRoles(Arrays.asList("admin"));
user.setPermissions(Arrays.asList("user:select", "user:update", "user:delete"));
return user;
} else {
return null;
}
}
}
2.4 编写授权和鉴权代码
在Controller中编写授权和鉴权代码,实现对鉴权失败的情况进行处理。
@RestController
public class UserController {
@RequestMapping("/user/select")
public String selectUser() {
return "查询用户成功";
}
@RequestMapping("/user/update")
public String updateUser() {
return "更新用户信息成功";
}
@RequestMapping("/user/delete")
public String deleteUser() {
return "删除用户成功";
}
@RequestMapping("/unauthorized")
public String unauthorized() {
return "没有权限访问此页面";
}
}
2.5 测试
完成上述步骤后,运行程序并访问localhost:8080/login,输入admin/123456登录后,访问/user/select、/user/update、/user/delete,应该能正常访问,否则将会跳转到unauthorized页面。
三、总结
至此,我们已经完成了SpringBoot集成Shiro权限管理的简单实现。在使用过程中需要注意:
- 在自定义的Realm中返回的SimpleAuthenticationInfo对象中,第一个参数必须是用户对象。
- 自定义的Realm必须添加到SecurityManager中。
- 可以通过编写自定义的Filter实现更多的权限控制。
- 若需要对部分用户进行特殊处理,可以重新实现AuthorizingRealm的授权方法。
- 完整示例代码请参考GitHub上的开源项目。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:springboot集成shiro权限管理简单实现 - Python技术站