Spring Boot集成Shiro实现动态加载权限的完整步骤

下面我将为您详细讲解Spring Boot集成Shiro实现动态加载权限的完整步骤。

一、引入依赖

在Spring Boot项目中,需要引入以下依赖:

<!-- shiro依赖 -->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring-boot-web-starter</artifactId>
    <version>1.7.1</version>
</dependency>

<!-- mybatis-plus依赖 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.2.0</version>
</dependency>

<!-- druid依赖 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.5</version>
</dependency>

其中,shiro-spring-boot-web-starter是Shiro的Spring Boot集成依赖,mybatis-plus-boot-starter是Mybatis Plus的Spring Boot集成依赖,druid-spring-boot-starter是Druid连接池的Spring Boot集成依赖。

二、定义Shiro的Realm

在Spring Boot项目中,需要定义一个继承自AuthorizingRealm的Realm类,用于进行认证和授权操作。示例代码如下:

@Component
public class UserRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    /**
     * 认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String username = token.getUsername();
        User user = userService.getUserByUsername(username);
        if (user == null) {
            throw new UnknownAccountException("账号不存在");
        } else {
            return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
        }
    }

    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        User user = (User) principalCollection.getPrimaryPrincipal();
        List<Role> roleList = userService.getRoleListByUserId(user.getId());
        Set<String> roleSet = new HashSet<>();
        Set<String> permissionSet = new HashSet<>();
        for (Role role : roleList) {
            roleSet.add(role.getName());
            List<Permission> permissionList = userService.getPermissionListByUserIdAndRoleId(user.getId(), role.getId());
            for (Permission permission : permissionList) {
                permissionSet.add(permission.getName());
            }
        }
        authorizationInfo.setRoles(roleSet);
        authorizationInfo.setStringPermissions(permissionSet);
        return authorizationInfo;
    }
}

以上代码中,doGetAuthenticationInfo方法用于进行认证操作,根据用户名查询用户并返回认证信息;doGetAuthorizationInfo方法用于进行授权操作,根据用户的角色和权限进行授权。

三、配置Shiro的过滤器

在Spring Boot项目中,需要配置Shiro的过滤器,来控制用户访问URL的权限。示例代码如下:

@Configuration
public class ShiroConfig {

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        // 自定义过滤器,用于动态加载权限
        Map<String, Filter> filters = new LinkedHashMap<>();
        filters.put("perms", new CustomPermissionsAuthorizationFilter());
        shiroFilterFactoryBean.setFilters(filters);
        // 定义url过滤规则
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        // 配置不需要权限认证的url
        filterChainDefinitionMap.put("/login", "anon");
        // 配置需要权限认证的url
        filterChainDefinitionMap.put("/**", "perms");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    @Bean
    public SecurityManager securityManager(UserRealm userRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm);
        return securityManager;
    }

}

其中,定义了一个自定义过滤器CustomPermissionsAuthorizationFilter,用于动态加载权限,在后面会详细介绍;同时,还定义了url过滤规则,配置了不需要权限认证的url和需要权限认证的url。

四、配置Shiro的权限注解

在Spring Boot项目中,需要在需要控制权限的方法上添加Shiro的注解@RequiresPermissions。示例代码如下:

@RequiresPermissions("user:view")
@GetMapping("/list")
public Result list(@RequestParam(required = false) String username) {
    List<User> userList = userService.getUserList(username);
    return Result.success(userList);
}

以上代码中,使用了@RequiresPermissions("user:view")注解,表示用户需要具备“user:view”权限才能访问该方法。

五、实现动态加载权限

在Spring Boot项目中,实现动态加载权限需要定义一个自定义过滤器CustomPermissionsAuthorizationFilter。示例代码如下:

public class CustomPermissionsAuthorizationFilter extends PermissionsAuthorizationFilter {

    @Autowired
    private UserService userService;

    @Override
    public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
        Subject subject = getSubject(request, response);
        // 获取请求的url
        String url = getPathWithinApplication(request);
        // 获取当前用户的角色和权限
        User user = (User) subject.getPrincipal();
        List<Permission> permissionList = userService.getPermissionListByUrlAndUserId(url, user.getId());
        Set<String> permissionSet = new HashSet<>();
        for (Permission permission : permissionList) {
            permissionSet.add(permission.getName());
        }
        // 判断用户是否具备请求的url所需的权限
        return subject.isPermittedAll(permissionSet.toArray(new String[permissionSet.size()]));
    }

}

以上代码中,重写了父类的isAccessAllowed方法,用于实现动态加载权限。首先获取请求的url和当前用户的角色和权限信息,然后根据url和userId查询当前登录用户所具备的权限,最后判断用户是否具备请求的url所需的权限。

六、使用示例

以下是一个获取用户列表的Controller示例:

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/list")
    @RequiresPermissions("user:view")
    public Result list(@RequestParam(required = false) String username) {
        List<User> userList = userService.getUserList(username);
        return Result.success(userList);
    }

    @PostMapping("/add")
    @RequiresPermissions("user:add")
    public Result add(@RequestBody User user) {
        userService.addUser(user);
        return Result.success();
    }

}

其中,@RequiresPermissions("user:view")@RequiresPermissions("user:add")注解用于控制用户访问该方法的权限。

另外,还需要进行登录认证才能访问受控的URL,登录认证代码如下:

@PostMapping("/login")
public Result login(@RequestBody User user) {
    UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());
    Subject subject = SecurityUtils.getSubject();
    try {
        subject.login(token);
        return Result.success("登录成功");
    } catch (AuthenticationException e) {
        return Result.error(e.getMessage());
    }
}

小结

以上就是Spring Boot集成Shiro实现动态加载权限的完整步骤,包括引入依赖、定义Shiro的Realm、配置Shiro的过滤器、配置Shiro的权限注解以及实现动态加载权限。其中,完成一个自定义过滤器用于动态加载权限是实现该功能的关键所在。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Boot集成Shiro实现动态加载权限的完整步骤 - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • vue中添加mp3音频文件的方法

    下面是详细讲解 Vue 中添加 mp3 音频文件的方法的完整攻略。 1.准备工作 在 Vue 项目的 public 目录下创建 audio 目录,并将需要添加的 mp3 音频文件放置在该目录下。 2.添加音频标签 在需要添加音频的组件中,使用 HTML5 音频标签 audio,并为其设置 src 属性为音频文件的相对路径: <audio src=&qu…

    Vue 2023年5月27日
    00
  • mpvue构建小程序的方法(步骤+地址)

    mpvue是一款基于Vue.js框架的小程序前端开发框架,它可以实现在小程序中使用Vue.js的语法和开发方式,极大地提高了小程序的开发效率和代码质量。下面我将详细讲解如何使用mpvue构建小程序。 步骤 安装mpvue脚手架工具 npm install -g vue-cli vue init mpvue/mpvue-quickstart my-projec…

    Vue 2023年5月27日
    00
  • 使用Vue3实现一个Upload组件的示例代码

    请允许我来详细讲解”使用Vue3实现一个Upload组件的示例代码”的完整攻略。 第一步:安装vue3 首先,我们需要安装Vue.js 3,可以通过以下命令进行安装: npm install vue@next 第二步:安装依赖 接下来,我们还需要安装一些依赖,包括 axios 以及 @vue/cli-plugin-babel,可以通过以下命令进行安装: np…

    Vue 2023年5月28日
    00
  • 关于Vue3中defineProps用法图文详解

    什么是 defineProps?defineProps 是 Vue3 中一种新的组件数据传递方式,可以用于在子组件中定义接收哪些父组件的 props。当父组件的 props 发生变化时,子组件也会随之响应。 如何使用 defineProps?在子组件中可以使用 defineProps 声明该组件需要接收的 props,它需要传递一个包含 props 字段的对…

    Vue 2023年5月28日
    00
  • vue请求本地自己编写的json文件的方法

    介绍如下: 一、准备JSON文件 首先,需要准备好本地的JSON文件,示例文件可以参考以下结构: { "data": [ { "id": 1, "title": "文章1", "content": "这是文章1的内容" }, { &quot…

    Vue 2023年5月28日
    00
  • vue常用事件v-on:click详解事件对象,事件冒泡,事件默认行为

    Vue.js是一种基于组件的JavaScript框架,使用它可以快速地构建Web应用程序,并且在处理用户交互时会涉及到许多事件。在Vue.js中,使用 v-on:click 事件指令来监听用户单击按钮和其他DOM元素的事件。在本攻略中,我们将讨论 v-on:click 事件的事件对象,事件冒泡以及事件默认行为。 事件对象 当使用v-on:click事件指令时…

    Vue 2023年5月28日
    00
  • vue中的H5移动端项目 真机测试配置方式

    配置Vue H5移动端项目在真机上进行测试有以下几个步骤: 步骤一:检查移动设备与电脑是否连接同一WiFi或有线网络 确保移动设备与调试电脑处于同一WiFi或有线网络环境中,且两者可以互相访问。这可以使用ping命令检查网络是否正常。 示例: 假设移动设备的IP地址为192.168.0.100,调试电脑的IP地址为192.168.0.101。在电脑的命令行中…

    Vue 2023年5月28日
    00
  • Vue模拟响应式原理底层代码实现的示例

    下面我将为你详细讲解“Vue模拟响应式原理底层代码实现的示例”的完整攻略。 什么是Vue模拟响应式原理 在Vue框架中,响应式原理是Vue实现数据绑定的重要原理,它通过数据劫持、观察者模式等技术实现了数据的变化能够自动地触发视图的更新。 在实际开发中,我们有时需要自己实现响应式原理,并且Vue框架的响应式原理实现也是值得我们去学习的。 实现方法 Vue官方提…

    Vue 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部