SpringBoot整合Shiro实现用户权限管理

核心API:
  1. Subject:用户主体(把操作交给SecurityManager)
  2. SecurityManager:安全管理器(关联Realm)
  3. Realm:Shiro连接数据的桥梁(从数据库中获取数据)
Shiro内置过滤器:
  1. anon:无需认证(登录)可以访问
  2. authc:必须认证才可以访问
  3. user:如果使用RememberMe的功能可以直接访问
  4. perms:该资源必须得到资源权限才可以访问
  5. role:该资源必须得到角色权限才可以访问
Shiro配置文件:
@Configuration
public class ShiroConfig {
    /**
     * 创建ShiroFilterFactoryBean
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        //添加Shiro过滤器
        Map<String,String> map = new LinkedHashMap<>();
        //添加授权信息,为每个请求地址设置访问权限
        //perms后括号内的参数设置:为该请求设置一个名称,后期将权限名称保存在数据库中,通过查询用户是否有这些名称来判断用户是否拥有此类权限
        map.put("/","anon");
        map.put("/index","authc");
        map.put("/delDepart","perms[depart:del]");
        map.put("/editDepart","perms[depart:edit]");
        map.put("/addDepart","perms[depart:add]");
        map.put("/delUser","perms[user:del]");
        map.put("/editUser","perms[user:edit]");

        //设置未授权跳转页面
        shiroFilterFactoryBean.setUnauthorizedUrl("/noPerm");
        //设置未登录跳转页面
        shiroFilterFactoryBean.setLoginUrl("/");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }
    /**
     * 创建DefaultWebSecurityManager安全管理器
     */
    @Bean(name = "defaultWebSecurityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        //关联Reaml
        defaultWebSecurityManager.setRealm(userRealm);
        return defaultWebSecurityManager;
    }
    /**
     * 创建Realm
     */
    @Bean(name = "userRealm")
    public UserRealm getReaml(){
        return new UserRealm();
    }
}
Realm实现(授权与身份认证):
//Realm:用于连接数据
public class UserRealm extends AuthorizingRealm {
    //用户service
    @Autowired
    UserService userService;
    //角色service
    @Autowired
    RoleService roleService;
    //用户权限service
    @Autowired
    RolePermService rolePermService;
    /**
     * 重写执行授权逻辑的方法
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行授权逻辑!");
        //给资源进行授权
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //创建一个用户主体,来获取登录的用户信息
        Subject subject = SecurityUtils.getSubject();
        //user对象是通过楼下认证逻辑方法中SimpleAuthenticationInfo传递的
        Users user1 = (Users) subject.getPrincipal();
        //通过获取到的用户对象,使用用户对象中的角色id去用户权限表(rolePerm)中或获取该角色的权限
        List<String> list = new ArrayList<>();
        list = rolePermService.findAllPermCode(user1.getRole_id());
        //添加资源的授权字段,此时该用户以及完成被授权的所有操作
        info.addStringPermissions(list);
        return info;
    }

    /**
     * 重写执行认证逻辑的方法:主要用来做用户登录认证
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("执行认证逻辑!");

        //编写shiro判断逻辑,验证用户名和密码
        //判断用户名(通过controller层发送过来的用户token中封装的用户的账号密码)
        UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
        Users user = new Users();
        user = userService.findUserByName(token.getUsername());
        if (user==null){
            return null;//shiro底层会抛出UnknownAccountException
        }
        //判断密码,第一个参数:传一个user对象给楼上授权逻辑的subject.getPrincipal();第二个参数:获取数据库中的密码,与传来的token中的密码对比;第三个参数:getName() 当前的realm名,可不写
        return new SimpleAuthenticationInfo(user,user.getPassword(),"");
    }
}
Shiro登录(Controller):
@RequestMapping("/doLogin")
    public String doLogin(String username, String password, HttpServletRequest request){
        /**
         * Shrio认证
         */
        //1、获取Subject
        Subject subject = SecurityUtils.getSubject();
        //2、封装用户数据
        UsernamePasswordToken token = new UsernamePasswordToken(username,password);
        //3、执行登录方法
        try{
            //登录验证,会去找Reaml的doGetAuthenticationInfo进行逻辑认证
            subject.login(token);
            //验证成功跳转到index
            return "redirect:/index";
        }catch (UnknownAccountException e){
        //UnknownAccountException:用户名找不到异常,return到登录页面
            return "redirect:/";
        }catch (IncorrectCredentialsException e){
        //IncorrectCredentialsException:密码错误异常,return到登录页面
            return "redirect:/";
        }
     }
Shiro与Thymeleaf整合:
依赖:
<!-- thymeleaf对shiro的扩展坐标 -->
<dependency>
    <groupId>com.github.theborakompanioni</groupId>
    <artifactId>thymeleaf-extras-shiro</artifactId>
    <version>2.0.0</version>
</dependency>
Shiro配置文件:
//需要在shiro配置文件中增加一个方法,用于thymeleaf和shiro标签配合使用
public ShrioDialect getShiroDialect(){
    return new ShiroDialect(); 
}
前端页面:

shiro:hasPermission 作用:
用于判断用户是否拥有这个权限,有则显示这个div,没有则不显示。

<div shiro:hasPermission="user:add">
进入用户添加功能:<a href="add">用户添加</a><br/>
</div>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值