shiro在springboot中的使用以及权限管理的实现

在Spring Boot中使用Shiro:

1.添加Shiro依赖

在Maven中添加以下依赖:

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring-boot-starter</artifactId>
    <version>1.4.2</version>
</dependency>

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<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.使用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<User> userList = userService.findAllUsers();
    
    // 返回用户列表页面
    return "users";
}

在Shiro中,可以使用@RequiresPermissions注解来限制用户的访问权限,具体步骤如下:

  1. 定义权限

在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<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.在Controller方法中使用权限控制

在需要进行权限控制的方法上,使用@RequiresPermissions注解,指定需要的权限。例如,可以在UserController中实现如下代码:

@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";
}

在上述代码中,使用@RequiresPermissions注解限制了用户访问/users路径下的不同HTTP方法所需要的权限,例如listaddeditdelete。如果用户没有足够的权限,将会抛出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的基本使用啦~~

猜你喜欢

转载自blog.csdn.net/qq_56921846/article/details/132662931