Using Shiro with Spring Boot:
1. Add Shiro dependency
Add the following dependencies in Maven:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.4.2</version>
</dependency>
2. Configure Shiro
application.properties
Add the following configuration to the file :
# Shiro配置
shiro:
# 启用Shiro
enabled: true
# 配置Realm
realm:
# 指定自定义的Realm类
type: com.example.demo.shiro.CustomRealm
# 配置加密算法
credentialsMatcher:
hashAlgorithmName: md5
hashIterations: 2
3. Implement custom Realm
Create a CustomRealm
class, inherit AuthorizingRealm
, and implement doGetAuthenticationInfo()
and doGetAuthorizationInfo()
methods.
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<Role> roles = userService.findRolesByUserId(user.getId());
List<Permission> 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. Use Shiro for authentication
Where identity authentication is required, such as in the Controller, the following code can be used for authentication:
@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. Use Shiro for permission control
Where permission control is required, such as methods in Controller, the following annotations can be used for control:
@RequiresPermissions("user:list")
@GetMapping("/users")
public String listUsers() {
// 查询用户列表
List<User> userList = userService.findAllUsers();
// 返回用户列表页面
return "users";
}
In Shiro, @RequiresPermissions
annotations can be used to restrict user access rights. The specific steps are as follows:
- define permissions
In Shiro, permissions are usually represented by strings, and permission strings can be defined according to application scenarios. For example, user
the following permissions can be defined under a module:
user:list
: view user listuser:add
:New usersuser:edit
: edit useruser:delete
:delete users
2. Authorize in Realm
In the method of Realm doGetAuthorizationInfo()
, the permission string owned by the user can be added to the authorization information according to the user's role, permission and other information. For example, CustomRealm
the following code can be implemented in:
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
// 获取当前用户信息
User user = (User) principalCollection.getPrimaryPrincipal();
// 获取用户角色和权限信息
List<Role> roles = userService.findRolesByUserId(user.getId());
List<Permission> 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. Use permission control in the Controller method
On methods that require permission control, use @RequiresPermissions
annotations to specify the required permissions. For example, UserController
the following code can be implemented in:
@RequiresPermissions("user:list")
@GetMapping("/users")
public String listUsers(Model model) {
// 查询用户列表
List<User> 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";
}
In the above code, @RequiresPermissions
annotations are used to limit /users
the permissions required by different HTTP methods under the user access path, such as list
, add
, edit
, delete
. An exception will be thrown if the user does not have sufficient permissions UnauthorizedException
.
When we use Shiro for user permission control, we usually need to create the following tables in the database:
1. User table ( user
)
It is used to store basic information of system users, including user names, passwords, etc.
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 table ( role
)
It is used to store the basic information of system roles, including role name, description, etc.
CREATE TABLE `role` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
`description` VARCHAR(100),
PRIMARY KEY (`id`)
);
3. Permission table ( permission
)
Used to store basic information about system permissions, including permission name, description, etc.
CREATE TABLE `permission` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
`description` VARCHAR(100),
PRIMARY KEY (`id`)
);
4. User role association table ( user_role
)
It is used to store the association information between system users and roles.
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 association table ( role_permission
)
It is used to store the associated information of system roles and permissions.
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的基本使用啦~~