SpringBoot整合Shiro(三)——shiro的角色和权限拦截且进行授权

1、进行权限拦截和进行授权

    在shiroConfig中配置内置过滤,进行设置安全管理器,然后进行配置shiro的内置过滤器,filterMap.put("/user/update","perms[user:update]");,且进行拦截时,跳转到未授权页面:bean.setUnauthorizedUrl("/unauth");,代码如下所示:

package com.ygl.config;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author ygl
 * @description
 * @date 2020/11/6 10:37
 */
@Configuration
public class ShiroConfig {

    //ShiroFilterFactoryBean  过滤 (第三步:连接到前端)
    @Bean
        public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);
        //配置shiro的内置过滤器
        /*
            anon:匿名拦截器,不需要登录即可访问的资源,匿名用户或游客,一般用于过滤静态资源。
            authc:需要认证登录才能访问
            user:用户拦截器,表示必须存在用户
            perms:权限授权拦截器,验证用户是否拥有权限
                参数可写多个,表示需要某些权限才能通过,多个参数时写 perms[“user, admin”],当有多个参数时必须每个参数都通过才算可以
            roles:角色授权拦截器,验证用户是或否拥有角色。
                   参数可写多个,表示某些角色才能通过,多个参数时写 roles[“admin,user”],当有多个参数时必须每个参数都通过才算通过

         */
        //拦截
        Map<String, String> filterMap = new LinkedHashMap();
        //授权,正常情况下,没有授权的会跳到未授权页面  添加某个权限才可以
//        filterMap.put("/user/add","perms[user:add]");
//        filterMap.put("/user/update","perms[user:update]");

        //授权   添加某个角色才可以
        filterMap.put("/user/add","roles[admin]");

        //拦截
        filterMap.put("/toLogin","anon");
//        filterMap.put("/user/add","authc");
//        filterMap.put("/user/update","authc");
        filterMap.put("/user/*","authc");
        bean.setFilterChainDefinitionMap(filterMap);

        //被拦截时 设置登录的请求
        bean.setLoginUrl("/toLogin");
        //跳转到未授权页面
        bean.setUnauthorizedUrl("/unauth");

        return bean;
    }

    //DafaultWebSecurityManager 安全对象  (第二步:接管对象)
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联userRealm
        securityManager.setRealm(userRealm);

        return securityManager;

    }


    //创建Realm对象  需要自定义 (第一步:创建对象)
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }

}

主要修改代码在这里,perms 代表赋予权限
在这里插入图片描述
然后在Realm中的授权中设置拥有这些权限的可以进行授权,代码分析如下:

package com.ygl.config;

import com.ygl.pojo.User;
import com.ygl.service.UserSevice;
import com.ygl.utils.PasswordUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @author ygl
 * @description
 * @date 2020/11/6 10:41
 */
//自定义的 UserRealm
public class UserRealm extends AuthorizingRealm {
    @Autowired
    private UserSevice userSevice;


    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了授权功能=》doGetAuthorizationInfo!");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //进行授权
//        info.addStringPermission("user:add");
        //获取当前对象
        Subject subject = SecurityUtils.getSubject();
        //从认证中拿到当前登录的user对象
        User currentUser = (User) subject.getPrincipal();
        //设置当前用户的权限
        info.addStringPermission(currentUser.getPerms());
        //设置角色
//        info.addRole(currentUser.getRole());

        return info;
    }
    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("执行了认证功能=》doGetAuthorizationInfo!");

        UsernamePasswordToken userToken = (UsernamePasswordToken)token;
        //连接真实数据库
        User user = userSevice.queryByName(userToken.getUsername());
        //pwd代表是用户输入的密码数据
        String pwd ="";
        for (int i = 0; i < userToken.getPassword().length; i++) {
            pwd =pwd +userToken.getPassword()[i];
        }
        if (user == null){
            return null;
        }

        /*
        System.out.println("密码:"+user.getPwd());
         */
        // 获取盐值
        String salt = user.getSalt();
        String password = PasswordUtils.getMd5(pwd, user.getName(), salt);
        char[] chars = password.toCharArray();
        userToken.setPassword(chars);
        System.out.println("password:"+password);
        //密码认证   shiro来进行操作,防止获取到密码
        return new SimpleAuthenticationInfo(user,user.getPwd(),user.getName());

    }
}

主要更改内容如下图所示:
在这里插入图片描述
注意: 在realm中,如果需要从认证中查询到的用户信息传到授权中时,需要在认证代码中的密码验证中进行将用户信息传值过来,如下图所示:
在这里插入图片描述

2、进行角色授权

   角色的授权拦截和权限的授权拦截基本上一致,只是在filterMap.put("/user/update","perms[user:update]");代码中的perms更改成roles,也就是更改成filterMap.put("/user/add","roles[admin]");,如下图所示:
在这里插入图片描述
在shiroConfig类中更改为进行角色授权,也就是由info.addStringPermission(currentUser.getPerms());更改为info.addRole(currentUser.getRole());,代码修改如下图所示:
在这里插入图片描述

注意:

    角色和权限这两个是从数据库中查询到的,在实体类中大家记得添加属性。

### Spring Boot 前后端分离 Shiro 整合实现用户认证权限管理 #### 项目搭建与依赖引入 为了构建支持前后端分离并集成了Shiro安全机制的Spring Boot应用,首先需要创建一个新的Spring Boot项目,并添加必要的依赖项。除了常规的Web开发所需依赖外,还需加入Apache Shiro的相关库来负责安全控制。 ```xml <dependencies> <!-- 其他基础依赖 --> <!-- shiro --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency> </dependencies> ``` 此部分描述了如何设置项目的初始结构以及所需的Maven坐标以包含Shiro功能[^1]。 #### 配置Shiro过滤器链定义 在`application.properties`文件或者通过Java配置类中指定Shiro Filter Chain Definitions, 定义哪些URL模式应该被哪种类型的拦截器处理。特别需要注意的是路径匹配规则中的顺序问题;更具体的路径应当优先于通配符路径声明,以免影响预期的行为。 例如,在配置文件里可以这样写: ```properties # application.properties 中的部分内容 shiro.filterChainDefinitions= /css/**=anon,/js/**=anon,/images/**=anon,/login=anon, /**=authc ``` 这里指出了对于静态资源(如CSS、JavaScript 文件)允许匿名访问(`anon`),而其他所有请求则需经过身份验证(`authc`)才能继续[^3]。 #### 自定义SecurityManager Bean Realm 实现 为了让Shiro能够理解应用程序特有的逻辑——比如从数据库加载用户的凭证信息或角色分配情况,则通常还需要自定义`Realm`组件并与之关联起来的一个`SecurityManager` bean实例。这一步骤涉及到编写相应的Java代码片段用于扩展AbstractAuthorizingRealm抽象基类,并重载其中的方法完成具体业务需求。 ```java @Configuration public class ShiroConfig { @Bean(name = "securityManager") public DefaultWebSecurityManager securityManager(MyCustomRealm myCustomRealm){ DefaultWebSecurityManager manager = new DefaultWebSecurityManager(); manager.setRealm(myCustomRealm); return manager; } } ``` 上述代码展示了怎样注册一个名为`securityManager`的服务对象给IoC容器的同时注入了一个实现了定制化realm接口的对象作为参数传递进去。 #### 处理前端发送过来的身份验证请求 当采用RESTful API风格设计时,客户端会向服务器提交带有用户名密码的数据包来进行登录操作。此时可以在控制器层面上捕获这些POST调用并通过Shiro提供的工具方法尝试建立有效的Subject上下文环境。 ```java @PostMapping("/doLogin") @ResponseBody public String doLogin(@RequestParam String username,@RequestParam String password){ Subject currentUser = SecurityUtils.getSubject(); if (!currentUser.isAuthenticated()) { UsernamePasswordToken token = new UsernamePasswordToken(username,password); try{ currentUser.login(token); // 尝试登陆... return "success"; }catch (AuthenticationException e){ return "failure"; } } ... } ``` 这段程序说明了接收来自HTTP POST请求携带的信息之后利用Shiro框架内部封装好的API去校验传入账号的有效性[^2]。 #### 结论 综上所述,通过合理规划项目模块间的协作关系,适当调整中间件层面的各项设定再加上精心编写的后台服务端口就能顺利达成基于Spring Boot平台之上运用Shiro技术栈实施细粒度级别的访问控制目标。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岭岭颖颖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值