在Spring Boot中使用Shiro:
1.添加Shiro依赖
在Maven中添加以下依赖:
org.apache.shiro
shiro-spring-boot-starter
1.4.2
2.配置Shiro
在application.properties
文件中添加以下配置:
# Shiro配置
shiro:
# 启用Shiro
enabled: true
# 配置Realm
realm:
# 指定自定义的Realm类
type: com.example.demo.shiro.CustomRealm
# 配置加密算法
credentialsMatcher:
hashAlgorithmName: md5
hashIterations: 2
3.实现自定义Realm
创建一个CustomRealm
类,继承AuthorizingRealm
,并实现doGetAuthenticationInfo()
和doGetAuthorizationInfo()
方法。
public class CustomRealm extends AuthorizingRealm {
/**
* 用户认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
// 获取用户名和密码
String username = (String) authenticationToken.getPrincipal();
String password = new String((char[]) authenticationToken.getCredentials());
// 根据用户名查询用户信息
User user = userService.findUserByUsername(username);
if (user == null) {
throw new UnknownAccountException();
}
// 校验密码
if (!password.equals(user.getPassword())) {
throw new IncorrectCredentialsException();
}
// 返回认证信息
return new SimpleAuthenticationInfo(user, password, getName());
}
/**
* 用户授权
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
// 获取当前用户信息
User user = (User) principalCollection.getPrimaryPrincipal();
// 获取用户角色和权限信息
List roles = userService.findRolesByUserId(user.getId());
List permissions = userService.findPermissionsByUserId(user.getId());
// 添加角色和权限信息到授权信息中
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
for (Role role : roles) {
authorizationInfo.addRole(role.getName());
}
for (Permission permission : permissions) {
authorizationInfo.addStringPermission(permission.getName());
}
// 返回授权信息
return authorizationInfo;
}
}
4.使用Shiro进行身份认证
在需要进行身份认证的地方,例如Controller中,可以使用以下代码进行认证:
@PostMapping("/login")
public String login(String username, String password) {
// 创建用户名密码Token
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
// 获取Subject
Subject subject = SecurityUtils.getSubject();
try {
// 登录
subject.login(token);
// 认证成功
return "redirect:/home";
} catch (AuthenticationException e) {
// 认证失败
return "redirect:/login?error=true";
}
}
5.使用Shiro进行权限控制
在需要进行权限控制的地方,例如Controller中的方法,可以使用以下注解进行控制:
@RequiresPermissions("user:list")
@GetMapping("/users")
public String listUsers() {
// 查询用户列表
List userList = userService.findAllUsers();
// 返回用户列表页面
return "users";
}
在Shiro中,可以使用@RequiresPermissions
注解来限制用户的访问权限,具体步骤如下:
在Shiro中,权限通常使用字符串表示,可以根据应用场景自行定义权限字符串。例如,可以在user
模块下定义以下权限:
user:list
:查看用户列表user:add
:新增用户user:edit
:编辑用户user:delete
:删除用户2.在Realm中授权
在Realm的doGetAuthorizationInfo()
方法中,可以根据用户的角色、权限等信息,将其拥有的权限字符串添加到授权信息中。例如,可以在CustomRealm
中实现如下代码:
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
// 获取当前用户信息
User user = (User) principalCollection.getPrimaryPrincipal();
// 获取用户角色和权限信息
List roles = userService.findRolesByUserId(user.getId());
List permissions = userService.findPermissionsByUserId(user.getId());
// 添加角色和权限信息到授权信息中
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
for (Role role : roles) {
authorizationInfo.addRole(role.getName());
}
for (Permission permission : permissions) {
authorizationInfo.addStringPermission(permission.getName());
}
// 返回授权信息
return authorizationInfo;
}
3.在Controller方法中使用权限控制
在需要进行权限控制的方法上,使用@RequiresPermissions
注解,指定需要的权限。例如,可以在UserController
中实现如下代码:
@RequiresPermissions("user:list")
@GetMapping("/users")
public String listUsers(Model model) {
// 查询用户列表
List userList = userService.findAllUsers();
// 将用户列表添加到Model中
model.addAttribute("userList", userList);
// 返回用户列表页面
return "users";
}
@RequiresPermissions("user:add")
@PostMapping("/users")
public String addUser(User user) {
// 新增用户
userService.addUser(user);
// 返回用户列表页面
return "redirect:/users";
}
@RequiresPermissions("user:edit")
@PutMapping("/users/{id}")
public String editUser(@PathVariable("id") Long id, User user) {
// 更新用户信息
userService.updateUser(id, user);
// 返回用户列表页面
return "redirect:/users";
}
@RequiresPermissions("user:delete")
@DeleteMapping("/users/{id}")
public String deleteUser(@PathVariable("id") Long id) {
// 删除用户
userService.deleteUser(id);
// 返回用户列表页面
return "redirect:/users";
}
在上述代码中,使用@RequiresPermissions
注解限制了用户访问/users
路径下的不同HTTP方法所需要的权限,例如list
、add
、edit
、delete
。如果用户没有足够的权限,将会抛出UnauthorizedException
异常。
我们在使用Shiro进行用户权限控制时,通常需要在数据库中建立以下几张表:
1.用户表(user
)
用于存储系统用户的基本信息,包括用户名、密码等。
CREATE TABLE `user` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(50) NOT NULL,
`password` VARCHAR(100) NOT NULL,
PRIMARY KEY (`id`)
);
2.角色表(role
)
用于存储系统角色的基本信息,包括角色名称、描述等。
CREATE TABLE `role` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
`description` VARCHAR(100),
PRIMARY KEY (`id`)
);
3.权限表(permission
)
用于存储系统权限的基本信息,包括权限名称、描述等。
CREATE TABLE `permission` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
`description` VARCHAR(100),
PRIMARY KEY (`id`)
);
4.用户角色关联表(user_role
)
用于存储系统用户与角色的关联信息。
CREATE TABLE `user_role` (
`user_id` BIGINT(20) NOT NULL,
`role_id` BIGINT(20) NOT NULL,
PRIMARY KEY (`user_id`, `role_id`),
CONSTRAINT `fk_user_role_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`),
CONSTRAINT `fk_user_role_role_id` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`)
);
5.角色权限关联表(role_permission
)
用于存储系统角色与权限的关联信息。
CREATE TABLE `role_permission` (
`role_id` BIGINT(20) NOT NULL,
`permission_id` BIGINT(20) NOT NULL,
PRIMARY KEY (`role_id`, `permission_id`),
CONSTRAINT `fk_role_permission_role_id` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`),
CONSTRAINT `fk_role_permission_permission_id` FOREIGN KEY (`permission_id`) REFERENCES `permission` (`id`)
);
以上就是shiro的基本使用啦~~