springboot整合shiro


springboot 整合shiro

一、shiro是什么?

概念: Apache Shiro 是一个强大且易用的 Java 安全框架
能做什么:Shiro可以帮我们完成 :认证、授权、加密、会话管理、与 Web 集成、缓存等。
在这里插入图片描述
主要认识::
Subject(用户):当前的操作用户 获取当前用户Subject currentUser = SecurityUtils.getSubject()
SecurityManager(安全管理器):Shiro的核心,负责与其他组件进行交互,实现 subject 委托的各种功能
Realms(数据源) :Realm会查找相关数据源,充当与安全管理间的桥梁,经过Realm找到数据源进行认证,授权等操作
Authenticator(认证器): 用于认证,从 Realm 数据源取得数据之后进行执行认证流程处理。
Authorizer(授权器):用户访问控制授权,决定用户是否拥有执行指定操作的权限。
SessionManager (会话管理器):支持会话管理
CacheManager (缓存管理器):用于缓存认证授权信息
Cryptography(加密组件):提供了加密解密的工具包

二、与springboot的整合

1.前期准备

数据库5张表:用户表 角色表 权限表 用户与角色的中间表 角色与权限的中间表
在这里插入图片描述
创建spring boot项目 导入所需要的依赖 相应的配置文件 shiro thymeleaf mybatis mysql等

页面准备:登录 主页面 等一些界面
在这里插入图片描述

2.ShiroConfiger配置类

@Configuration
public class ShiroConfiger {
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
        //关联默认的web安全管理
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        return shiroFilterFactoryBean;
    }

    @Bean(name = "defaultWebSecurityManager")
    public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager();
        //关联realm
        defaultWebSecurityManager.setRealm(userRealm);
        return  defaultWebSecurityManager;
    }

    //绑定
    @Bean(name = "userRealm")
    public UserRealm userRealm(){
        return  new UserRealm();
    }
}

自定义realm(认证授权)

public class UserRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
  
        return  null;
    }
}

3.过滤(拦截)

过滤规则:anon 指定url可以匿名访问 authc 需登录 authcBasic 指定url需要http认证 logout 退出登录url user需要已登录或者记住我才能访问 roles 拥有某个角色才能进入 perms 拥有某个权限才能进入等

@Configuration
public class ShiroConfiger {
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
        //关联默认的web安全管理
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        //过滤
        //过滤规则 anon 指定url可以匿名访问 authc 需登录 authcBasic 指定url需要http认证 logout 退出登录url  user需要已登录或者记住我才能访问
        //roles 拥有某个角色才能进入 perms 拥有某个权限才能进入
        Map<String,String> map=new HashMap<>();
        map.put("/user/add","perms[/user/add]");
        map.put("/user/update","perms[/user/update]");
        map.put("/user/index","anon");
        map.put("/user/other","authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        //设置登录请求
        shiroFilterFactoryBean.setLoginUrl("/user/login");
        //设置无权限登录地址
        shiroFilterFactoryBean.setUnauthorizedUrl("/user/un");
        return shiroFilterFactoryBean;
    }

    @Bean(name = "defaultWebSecurityManager")
    public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager();
        //关联realm
        defaultWebSecurityManager.setRealm(userRealm);
        return  defaultWebSecurityManager;
    }

    //绑定
    @Bean(name = "userRealm")
    public UserRealm userRealm(){
        return  new UserRealm();
    }

书写相应的controller进行验证

4.认证

mapper层: public SysUser selectUser(@Param(“userName”) String userName); 查询数据库实现 通过用户名 查询到相应的对象
controller层:

 @RequestMapping("/login2")
    public String toLogin2(@RequestParam("username") String username, @RequestParam("password") String password, Model model, ServletRequest request){
        //获取当前用户 subject==》》表示当前用户
        Subject subject = SecurityUtils.getSubject();
        //封装用户的信息 成一个UsernamePasswordToken令牌
        UsernamePasswordToken token=new UsernamePasswordToken(username,password);
        //一个try 两个catch  try 无异常执行登录        两catch  找不到账号 密码错误
        try {
                 subject.login(token);
            /*HttpServletRequest httpServletRequest= WebUtils.toHttp(request);
            HttpSession session=httpServletRequest.getSession();*/
                 return  "index";//未抛出异常 登录成功
        }catch (UnknownAccountException unknownAccountException){
            //账号未找到异常
            model.addAttribute("msg","账号未找到");
            return "login";
        }catch (IncorrectCredentialsException incorrectCredentialsException){
            //密码错误异常
            model.addAttribute("msg","密码错误");
            return "login";
        }

    }

自定义realm:

@Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //执行认证
        //当前的令牌 和 controller里面的令牌未同一个令牌
        UsernamePasswordToken usernamePasswordToken= (UsernamePasswordToken) authenticationToken;
        //查询数据库
        SysUser sysUser = userService.selectUser(usernamePasswordToken.getUsername());
        if (sysUser==null){
        //用户名查询为空 账号错误 返回为空 controller登录逻辑 抛出空异常
            return  null;
        }
        //密码认证shiro来做
        return  new SimpleAuthenticationInfo(sysUser,sysUser.getUserPassword(),"");
    }

5.授权

mapper层: public List selectUrl(@Param(“userName”) String userName); 5表联查 查询出账号所对应能访问的url地址

@Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //获取认证时传递的资源 第一个参数
        SysUser principal = (SysUser) subject.getPrincipal();
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
        //授权
        //获取当前用户的url地址集合
        List<String> list = userService.selectUrl(principal.getUserName());
         for (int i=0;i<list.size();i++){
              info.addStringPermission(list.get(i));
         }
        return info;
    }

6.注销

controller层:调用当前用户的logout方法 Subject subject = SecurityUtils.getSubject(); subject.logout();

7.显示问题(登录 注销同时显示 无权限地址显示等)

shiro配置类:

@Bean
    public ShiroDialect shiroDialect(){
        return new ShiroDialect();
    }

页面整合:

<html lang="en" xmlns:th="http://www.thymeleaf.org"  xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">

登录 注销显示:
controller:
将登录信息保存到session

 Session session=subject.getSession();
session.setAttribute("loginUser",token);

注销调用当前对象的logout方法

页面:

<div th:if="${session.loginUser!=null}">
    <a href="/user/logout">登出</a>
</div>

<div th:if="${session.loginUser==null}">
    <a href="/user/login">登录</a>
</div>

不显示无权限的地址
页面:

<div shiro:hasPermission="/user/add">
    <a href="/user/add">add</a>
</div>
<div shiro:hasPermission="/user/update">
    <a href="/user/update">update</a>
</div>
<a href="/user/other">other</a>

8.MD5加密

Md5Hash hash = new Md5Hash(“1”,“admin”,3);
参数:需要加密的字符 加盐(一般为用户名) 迭代次数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

别叹气了我走就是

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

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

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

打赏作者

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

抵扣说明:

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

余额充值