【Shiro】SpringBoot集成Shiro权限认证《下》

本章节是在上一节的基础上继续完成,如有不明白,请看上一篇文章【Shiro】SpringBoot集成Shiro权限认证《上》

SQL语句

这里我们需要先准备好SQL语句,如下所示:

/*
Navicat MySQL Data Transfer

Source Server         : local
Source Server Version : 50525
Source Host           : localhost:3306
Source Database       : new-shiro

Target Server Type    : MYSQL
Target Server Version : 50525
File Encoding         : 65001

Date: 2023-09-27 12:39:49
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for sys_permissions
-- ----------------------------
DROP TABLE IF EXISTS `sys_permissions`;
CREATE TABLE `sys_permissions` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `code` varchar(20) NOT NULL COMMENT '权限名称',
  `name` varchar(20) NOT NULL COMMENT '权限标识',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

-- ----------------------------
-- Records of sys_permissions
-- ----------------------------
INSERT INTO `sys_permissions` VALUES ('5', 'user:update', '用户修改');
INSERT INTO `sys_permissions` VALUES ('6', 'user:delete', '用户删除');

-- ----------------------------
-- Table structure for sys_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `code` varchar(50) DEFAULT NULL COMMENT '角色编码',
  `name` varchar(50) NOT NULL COMMENT '角色名称',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

-- ----------------------------
-- Records of sys_role
-- ----------------------------
INSERT INTO `sys_role` VALUES ('1', 'admin', '管理员');
INSERT INTO `sys_role` VALUES ('20', 'user', '普通用户');

-- ----------------------------
-- Table structure for sys_roles_permissions
-- ----------------------------
DROP TABLE IF EXISTS `sys_roles_permissions`;
CREATE TABLE `sys_roles_permissions` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `role_id` int(11) NOT NULL COMMENT '角色编号',
  `permission_id` int(11) NOT NULL COMMENT '权限编号',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `role_id` (`role_id`) USING BTREE,
  KEY `permission_id` (`permission_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='角色权限表';

-- ----------------------------
-- Records of sys_roles_permissions
-- ----------------------------
INSERT INTO `sys_roles_permissions` VALUES ('2', '20', '5');
INSERT INTO `sys_roles_permissions` VALUES ('5', '1', '5');
INSERT INTO `sys_roles_permissions` VALUES ('6', '1', '6');
-- ----------------------------
-- Table structure for sys_user
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `username` varchar(30) NOT NULL COMMENT '登录名',
  `password` varchar(255) NOT NULL COMMENT '用户密码',
  `name` varchar(30) DEFAULT NULL COMMENT '昵称',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `un_username_easyuser` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='用户表';

-- ----------------------------
-- Records of sys_user
-- ----------------------------
INSERT INTO `sys_user` VALUES ('1', 'admin', '123456', '小王');
INSERT INTO `sys_user` VALUES ('18', 'halo', '123456', 'Halo');

-- ----------------------------
-- Table structure for sys_users_roles
-- ----------------------------
DROP TABLE IF EXISTS `sys_users_roles`;
CREATE TABLE `sys_users_roles` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL COMMENT '用户编号',
  `role_id` int(11) NOT NULL COMMENT '角色编号',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `user_id` (`user_id`) USING BTREE,
  KEY `role_id` (`role_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='用户角色表';

-- ----------------------------
-- Records of sys_users_roles
-- ----------------------------
INSERT INTO `sys_users_roles` VALUES ('1', '1', '1');
INSERT INTO `sys_users_roles` VALUES ('12', '18', '20');


依赖引入


      <properties>
        <java.version>8</java.version>
        <mybatis-plus.version>3.1.1</mybatis-plus.version>
        <mysql.version>5.1.47</mysql.version>
        <alibaba.durid.version>1.0.9</alibaba.durid.version>
      </properties>
        <!--Mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>${mybatis-plus.version}</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus.version}</version>
        </dependency>
        <!--阿里巴巴连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${alibaba.durid.version}</version>
        </dependency>
        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>

代码生成

这里我们可以使用IDEA插件《EasyCode》生成Mybatis-Plus模板的后端代码。

生成的结果如下所示:

在这里插入图片描述

统一返回结果

这块是为了返回统一的结果,下面会用到。

Result.java

新建文件夹 common

@Data
public class Result<T> implements Serializable {

    private String code;
    private String message;
    private T data;

    public Result(String code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    public Result(ResultCodeEnum resultCodeEnum, T data) {
        this.code = resultCodeEnum.getCode();
        this.message = resultCodeEnum.getMessage();
        this.data = data;
    }

    public static <T> Result<T> success(T data) {
        return new Result<T>(ResultCodeEnum.SUCCESS, data);
    }

    public static Result fail(ResultCodeEnum resultCodeEnum) {
        return new Result(resultCodeEnum, "");
    }

}

ResultCodeEnum.java

新建文件夹 enums


public enum ResultCodeEnum {
    SUCCESS("0000", "操作成功"),
    SUCCESS_QUERY("0001", "查询成功"),
    SUCCESS_ADD("0002", "添加成功"),
    SUCCESS_UPDATE("0003", "更新成功"),
    SUCCESS_DELETE("0004", "删除成功"),


    TOKEN_ERROR("1000", "token错误"),
    TOKEN_NULL("1001", "token为空"),
    TOKEN_EXPIRED("1002", "token过期"),
    TOKEN_INVALID("1003", "token无效"),

    USER_ERROR("2000", "用户名密码错误"),
    USER_NOT_EXISTS("2001", "用户不存在"),
    USER_INVALID("2002", "用户无效"),
    USER_EXPIRED("2003", "用户过期"),
    USER_BLOCKED("2004", "用户封禁"),
    USER_PASSWORD_ERROR("2005", "密码错误"),

    PARAM_ERROR("3000", "参数错误"),
    PARAM_NULL("3001", "参数为空"),
    PARAM_FORMAT_ERROR("3002", "参数格式不正确"),
    PARAM_VALUE_INCORRECT("3003", "参数值不正确"),
    PARAM_DUPLICATE("3004", "参数重复"),
    PARAM_CONVERT_ERROR("3005", "参数转化错误"),

    AUTHORITY_ERROR("4000", "权限错误"),
    AUTHORITY_UNAUTHORIZED("4001", "无权限"),

    SERVER_ERROR("5000", "服务器内部错误"),
    SERVER_UNAVAILABLE("5001", "服务器不可用"),


    ;

    ResultCodeEnum(String code, String message) {
        this.code = code;
        this.message = message;
    }

    private String code;
    private String message;

    public String getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }
}

认证逻辑及授权

数据库操作逻辑

在SysUserService 新增 查询用户信息方法及查询角色、权限信息方法。

如下所示:

SysUserService.java

public interface SysUserService extends IService<SysUser> {

    /**
     * 根据用户名查询用户信息
     * @param userName
     * @return
     */
    SysUser queryUserInfoByUserName(String userName);

    /**
     * 根据用户ID查询用户角色、权限相关信息
     * @param userName
     * @return
     */
    SysUser queryUserInfoByUserInfo(String userName);
}

SysUserServiceImpl.java

@Service("sysUserService")
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Resource
    SysRoleMapper sysRoleMapper;

    @Resource
    SysPermissionsMapper sysPermissionsMapper;

    @Override
    public SysUser queryUserInfoByUserName(String userName) {
        return this.baseMapper.selectOne(new QueryWrapper<SysUser>().eq("username",userName));
    }

    @Override
    public SysUser queryUserInfoByUserInfo(String userName) {
        SysUser sysUser = this.baseMapper.selectOne(new QueryWrapper<SysUser>().eq("username",userName));
        List<SysRole> roleList = sysRoleMapper.querySysRoleByUserId(sysUser.getId());
        Set<SysPermissions> sysPermissionsSet = new HashSet<>();
        roleList.forEach(role->{
            sysPermissionsSet.addAll(this.sysPermissionsMapper.queryPermissionByRoleId(role.getId()));
        });
        sysUser.setSysRoleList(roleList);
        sysUser.setPermissionsSet(sysPermissionsSet);
        return sysUser;
    }
}

SysRoleMapper.java

public interface SysRoleMapper extends BaseMapper<SysRole> {

    /**
     * 根据用户ID查询角色信息
     * @param id
     * @return
     */
    @Select(" select t1.* from sys_role t1 inner join sys_users_roles t2 on t1.id = t2.role_id where t2.user_id = #{id} ")
    List<SysRole> querySysRoleByUserId(Integer id);
}

SysPermissionsMapper.java

/**
 * (SysPermissions)表数据库访问层
 *
 * @author halo-king
 * @since 2023-09-27 12:42:43
 */
public interface SysPermissionsMapper extends BaseMapper<SysPermissions> {
    /**
     * 根据角色ID查询角色信息
     * @param roleId
     * @return
     */
    @Select(" select t1.* from sys_permissions t1 inner join sys_roles_permissions t2 on t1.id = t2.permission_id where t2.role_id =#{roleId}")
    List<SysPermissions> queryPermissionByRoleId(Integer roleId);
}

在完成了数据库相关的操作逻辑后,我们需要修改 CustomerRealm 中的认证和授权逻辑。

认证

/**
     * 认证逻辑
     * @param authenticationToken
     * @return
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) {
        System.out.println("执行了=>认证逻辑AuthenticationToken");
        if(authenticationToken.getPrincipal()==null){
            return null;
        }
        UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
        SysUser sysUser = this.sysUserService.queryUserInfoByUserName(token.getUsername());

        if(sysUser == null){
            return null;
        }
        return  new SimpleAuthenticationInfo(sysUser.getUsername(), sysUser.getPassword(), getName());
    }

授权

 /**
     * 授权逻辑
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了=>授权逻辑PrincipalCollection");
        //获取登录用户名
        String userName = (String) principalCollection.getPrimaryPrincipal();
        SysUser sysUser = this.sysUserService.queryUserInfoByUserInfo(userName);

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        for (SysRole role : sysUser.getSysRoleList()) {
            //添加角色
            authorizationInfo.addRole(role.getCode());
            //添加权限
            for (SysPermissions permissions : sysUser.getPermissionsSet()) {
                authorizationInfo.addStringPermission(permissions.getCode());
            }
        }
        return authorizationInfo;
    }

统一接口返回

原来的登录接口

@GetMapping("/login")
    public String login(String userName,String passWord) {
        if (StringUtils.isEmpty(userName) || StringUtils.isEmpty(passWord)) {
            return "用户名密码不能为空";
        }
        //用户认证信息
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(userName, passWord);
        try {
            subject.login(usernamePasswordToken);
        } catch (UnknownAccountException e) {
            return "用户不存在";
        } catch (AuthenticationException e) {
            return "用户名密码错误";
        } catch (AuthorizationException e) {
            return "无权限登录";
        }
        return "登录成功";
    }

修改完后的登录接口

  @GetMapping("/login")
    public Result login(String userName, String passWord) {
        if (StringUtils.isEmpty(userName) || StringUtils.isEmpty(passWord)) {
            return Result.fail(ResultCodeEnum.USER_OR_PWD_NOT_EMPTY);
        }
        //用户认证信息
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(userName, passWord);
        try {
            subject.login(usernamePasswordToken);
        } catch (UnknownAccountException e) {
            return Result.fail(ResultCodeEnum.USER_NOT_EXISTS);
        } catch (AuthenticationException e) {
            return Result.fail(ResultCodeEnum.USER_ERROR);
        } catch (AuthorizationException e) {
            return Result.fail(ResultCodeEnum.AUTHORITY_UNAUTHORIZED);
        }
        return Result.success("登录成功");
    }

测试

登录测试

到这一步,我们就已经完成了登录和授权的操作,现在启动项目,测试。

不输入用户名和密码

访问地址:

    http://localhost:8082/login

返回结果:

{"code":"2006","message":"用户名或密码不能为空","data":""}

输入不存在的用户名和密码

访问地址:

http://localhost:8082/login?userName=test&passWord=123456

返回结果:

{"code":"2001","message":"用户不存在","data":""}

输入错误的用户名和密码

访问地址:

http://localhost:8082/login?userName=admin&passWord=12333

返回结果:

{"code":"2000","message":"用户名密码错误","data":""}

输入正确的用户名和密码

访问地址:

http://localhost:8082/login?userName=admin&passWord=123456

返回结果:

{"code":"0000","message":"操作成功","data":"登录成功"}

权限测试

注意:权限测试前提,需要先登录才行!!!

权限测试,我们分为方法授权和注解授权。
这里会列举一些小栗子,供大家参考。

通过上面的SQL,我们查询出用户admin 他具有角色为 admin 以及权限 user:update、user:delete.

方法授权

下面的代码,你可以方法放在LoginController 或者自己新建一个TestController 里面进行测试,都可。

@GetMapping("delete")
public Result delete() {
    Subject subject = SecurityUtils.getSubject();
    if(subject.isPermitted("user:delete")){
        return Result.success("delete success");
    }else{
        return Result.fail(ResultCodeEnum.AUTHORITY_UNAUTHORIZED);
    }
 }

访问地址:

http://localhost:8082/delete

返回结果:

{"code":"0000","message":"操作成功","data":"delete success"}

注解授权

当前用户拥有update,delete 但是没有 add 权限。

常规用的注解:

  • @RequiresAuthentication 需要完成用户登录
  • @RequiresGuest 未登录用户可以访问,登录用户不能访问
  • @RequiresPermissions 需要有对应资源权限
  • @RequiresRoles 需要有对应角色才能访问
  • @RequiresUser 需要用户完成登录并且实现了记住我功能
    @RequiresPermissions("user:update")
    @GetMapping("update")
    public Result<String> update() {
        return Result.success("update success ");
    }


    @RequiresPermissions("user:add")
    @GetMapping("add")
    public Result<String> add() {
        return Result.success("add success ");
    }

有权限

访问地址:

http://localhost:8082/update

返回结果:

{"code":"0000","message":"操作成功","data":"update success"}

无权限

访问地址:

http://localhost:8082/add

返回结果:

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Wed Sep 27 15:38:37 CST 2023
There was an unexpected error (type=Internal Server Error, status=500).
Subject does not have permission [user:add]

全局异常捕获

在上面的页面上,我们会发现,当出现没权有权限的时候,这样提示给用不是非常的不友好,所以,这里使用全局的异常捕获,给用户一个比较友好的体验。

新建一个exception文件夹,然后再文件加下新建 GlobalException.java

@Slf4j
@ControllerAdvice
public class GlobalException {

    @ExceptionHandler(AuthorizationException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.FORBIDDEN)
    public Result ExceptionHandler(AuthorizationException e) {
        // 打印堆栈,以供调试
        e.printStackTrace();
        return Result.fail(ResultCodeEnum.AUTHORITY_UNAUTHORIZED);
    }
    
    @ExceptionHandler(Exception.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result ExceptionHandler(Exception e) {
        // 打印堆栈,以供调试
        e.printStackTrace();
        return Result.fail(ResultCodeEnum.SERVER_ERROR);
    }

}

当我们再次测试上面的没有权限的接口时,返回的结果就是如下所示:

{"code":"4001","message":"无权限","data":""}

密码加密

密码加密

使用以下的代码,在新增用户的时候,生成密码

     System.out.println(new Md5Hash("123456", "YX"));

修改ShiroConfig

  /**
     * Shiro自带密码管理器
     *
     * @return HashedCredentialsMatcher
     */
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        //Shiro自带加密
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        //散列算法使用md5
        credentialsMatcher.setHashAlgorithmName("md5");
        //散列次数,2表示md5加密两次
        credentialsMatcher.setHashIterations(1);
        return credentialsMatcher;
    }

修改自定义Realm,即:密码验证那块逻辑。


/**
 * 认证逻辑
 * @param authenticationToken
 * @return
 */
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) {
        System.out.println("执行了=>认证逻辑AuthenticationToken");
        if(authenticationToken.getPrincipal()==null){
            return null;
        }
        UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
        SysUser sysUser = this.sysUserService.queryUserInfoByUserName(token.getUsername());

        if(sysUser == null){
            return null;
        }
        SimpleAuthenticationInfo  simpleAuthenticationInfo  = new SimpleAuthenticationInfo(sysUser.getUsername(), sysUser.getPassword(), getName());
        simpleAuthenticationInfo.setCredentialsSalt(ByteSource.Util.bytes("YX")); //加盐
        return  simpleAuthenticationInfo;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring Boot是基于Spring框架的快速开发应用程序的工具,而Shiro则是一个强大且灵活的Java安全框架。将Spring BootShiro结合使用可以实现权限管理的功能。 首先需要在Spring Boot项目中引入相关依赖,包括Spring Boot的依赖和Shiro的依赖。可以在pom.xml文件中添加如下依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.7.1</version> </dependency> ``` 接下来,需要配置Shiro的配置类。可以创建一个继承自org.apache.shiro.web.mgt.DefaultWebSecurityManager的类,并在该类中配置Shiro的相关信息,包括认证器和授权器。 认证器负责验证用户的身份,可以使用Shiro提供的Realm来实现自定义的身份验证逻辑。授权器负责判断用户是否有权限执行某个操作,可以使用Shiro提供的Permission类来实现权限的控制。 然后,需要为Spring Boot应用程序配置Shiro过滤器链。可以使用Shiro的FilterChainDefinitionMap类来配置URL与权限的映射关系。可以在一个继承自org.apache.shiro.web.env.AbstractWebEnvironment的类中配置这些过滤器链。 最后,在Spring Boot应用程序的入口类中启动Shiro配置。在main()方法中,可以使用org.apache.shiro.SecurityUtils类的setSecurityManager()方法来设置Shiro的安全管理器。 完成以上步骤后,Spring Boot应用程序就集成Shiro权限管理功能。可以通过编写相应的Controller和页面来测试权限管理的效果。 总之,通过将Spring BootShiro结合使用,可以实现权限管理的功能。通过配置Shiro的相关类和过滤器链,以及编写自定义的Realm和Permission,可以实现身份验证和权限控制的逻辑。 ### 回答2: Spring Boot是一个用于创建独立的、基于Spring的应用程序的框架。Shiro是一个强大的Java安全框架,提供了身份认证、授权、加密等安全功能。下面是使用Spring Boot集成Shiro权限管理的步骤和注意事项。 1. 添加依赖:在Maven或Gradle中添加Spring BootShiro的依赖项。 2. 创建Shiro配置类:创建一个继承自`org.apache.shiro.spring.config.ShiroAnnotationProcessorConfiguration`的配置类。在该类中配置Shiro的安全相关属性,比如加密算法、身份认证方式等。 3. 创建用户实体类:创建表示用户的实体类,并为其添加相关属性,如用户名、密码等。 4. 创建用户服务类:创建一个用户服务类,用于处理用户相关的操作,如用户注册、查询用户等。 5. 创建Realm类:创建一个继承自`org.apache.shiro.realm.AuthorizingRealm`的自定义Realm类。在该类中,实现身份认证和授权的逻辑。 6. 配置Shiro过滤器:在`application.properties`文件中配置Shiro的过滤器链,指定URL与权限之间的对应关系。 7. 创建Controller类:创建一个Controller类,用于处理用户请求。在该类中,通过`@RequiresRoles`和`@RequiresPermissions`等注解为方法添加授权需求。 8. 启动应用程序:使用Spring Boot的注解启动应用程序,让Spring Boot自动配置并启用Shiro。 注意事项: - 在配置Shiro时,需要根据实际需要选择适当的安全策略、加密算法和认证方式。 - 在自定义Realm类中,需要根据实际需求进行身份认证和授权的实现。 - 在通过Shiro注解为方法添加授权需求时,需要确保用户已经成功登录。 - 需要根据实际业务需求,合理配置Shiro的过滤器链,以获得所需的权限控制效果。 总之,使用Spring Boot集成Shiro权限管理可以方便地实现应用程序的安全认证和授权功能。通过配置Shiro的相关属性和自定义Realm类,可以实现灵活的权限管理,保护应用程序的安全。 ### 回答3: Spring Boot集成Shiro权限管理是一种常用的方式,可以实现安全的身份验证和授权功能。以下是一个简单的步骤,来演示如何实现这个集成。 第一步,导入相关依赖。在pom.xml文件中添加以下依赖项: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-web-starter</artifactId> <version>1.7.1</version> </dependency> ``` 第二步,编写Shiro的配置文件。创建一个类,命名为ShiroConfig,并使用@Configuration注解将其声明为一个配置类。在配置类中,使用@RequiresPermissions注解来定义URL的访问权限,使用@Bean注解来创建ShiroFilterFactoryBean和DefaultWebSecurityManager等Bean。 第三步,创建一个自定义的Realm类。这个类需要继承自AuthenticatingRealm,并实现其中的认证和授权方法。在认证方法中,需要根据用户名和密码来进行验证用户的身份。在授权方法中,需要判断用户是否具有访问某个URL的权限。 第四步,在Spring Boot的启动类中,添加@EnableCaching注解来启用缓存功能。这样可以提高系统的性能。 第五步,编写Controller类。在Controller中,使用@RequiresPermissions注解来定义URL的访问权限。在方法中,可以使用Subject进行身份验证和授权操作。 最后,启动应用程序。通过访问配置的URL,可以验证是否成功实现了Shiro权限管理功能。 通过以上步骤,我们可以实现Spring Boot集成Shiro权限管理。这样就可以在应用程序中实现安全的身份验证和授权功能,确保只有具备相应权限的用户可以访问指定的URL。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值