zoukankan      html  css  js  c++  java
  • Shiro

    1.Shiro介绍

    Shiro是一个java安全框架,执行身份验证,授权,密码,会话,Shiro是Apache的一个开源项目

    Shiro解决了应用安全的四要素:

    1.认证-用户身份识别

    2.授权-访问控制

    3.密码加密-保护或隐藏数据防止偷窥

    4.会话管理

    同时Shiro另外支持了一些辅助特性:如Web安全,单元测试,多线程

     

    2.Shiro的优势

    1.易于使用

    2.广泛性

    3.灵活性:Shiro可以工作在任何应用环境中,虽然他工作在Web,EJB和loC环境中,但他并不依赖这些环境。 Shiro即不强加任何规范,也无需过多依赖

    4.Web能力:Shiro对Web应用的支持很神奇,允许你基于应用URL和Web协议创建灵活的安全策略,同时还提 供了一套控制页面输出的JSP标签库

    5.可插拔:Shiro干净的API和设计模式使他可以方便的与许多其他框架进行集成,如Spring,Grails,Wicket, Tapestry,Mule,Apache Camel,Vaadin这类第三方框架无缝集成

     

    3.核心概念

    1.Subject:代表当前正在执行操作的用户,Subject代表的可以是人也可以是任何第三方系统账号。每个suject 实例都会被绑定到SercurityManger上

    2.SecurityManger:SecurityManger是Shiro核心,主要协调Shiro内部的各种安全组件,可以设置自定义的 Realm

    3.Realm:用户数据和Shiro数据交互的桥梁,比如用户身份认证,权限认证都需要使用Realm来读取数据

     

    4.SpringBoot整合Shiro

    1.导入Shiro依赖

    <!--shiro-->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>1.4.1</version>
            </dependency>

    2.配置登陆请求

    @RequestMapping(value = "/login")
        public String login(String usermane,String password,Model model ){
            //获得当前用户
            Subject subject = SecurityUtils.getSubject();
    
            //封装用户登陆的数据
            UsernamePasswordToken token = new UsernamePasswordToken(usermane, password);
            
            token.setRememberMe(true);//设置记住我 可以不设置
            try{
                //执行登陆操作(执行这个操作会跳转到Realm对象的认证方法)
                subject.login(token);
                return "index";
            }catch (UnknownAccountException uae){
                System.out.println("户名不存在:"+token.getPrincipal());
                model.addAttribute("msg","户名不存在");
                return "login";
            }catch (IncorrectCredentialsException ice){
                System.out.println("密码不正确:"+token.getPrincipal());
                model.addAttribute("msg","密码不正确");
                return "login";
            }catch (LockedAccountException lae){
                System.out.println("用户名帐户不正确,请联系管理员解锁"+token.getPrincipal());
                model.addAttribute("msg","用户名帐户不正确");
                return "login";
            }
        }

    3.配置ShiroConfig类

    shiro三要素
              ShiroFilterFactoryBean
              DefaultWebSecurityManager(SecurityManager)
              realm对象
              
    创建的时候从后向前创建
    1.先创建Realm对象
    
    //创建实体类继承AuthorizingRealm重写AuthorizingRealm类的方法
    public class UserRealm extends AuthorizingRealm {
    
        @Autowired
        private MyService myService;
    
        //授权方法
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
           
           System.out.println("执行授权方法=======》");
            
           SimpleAuthorizationInfo inof = new SimpleAuthorizationInfo();
           
           Users users = (Users)SecurityUtils.getSubject().getPrincipal();
           
           //给当前用户赋权限
           inof.setStringPermissions(users.getPerms());
    
           return inof;
        }
    
        //认证方法
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
            
            System.out.println("执行认证方法========》");
            
            //将AuthenticationToken转换为UsernamePasswordToken获得用户信息
            UsernamePasswordToken token=(UsernamePasswordToken)authenticationToken;
    
            Users users = myService.selectAll(token.getUsername());
    
            if(users==null){
                //如果用户名不一样返回null 他会自动抛出UnknowAccountException异常
                return null;
            }
            
            //获得当前用户的权限集合
            HashSet<String> perms=myService.selectPerms(users.getId());
    
            users.setPerms(perms);
    
            //进行密码认证,并将用户信息放入Sbject中
            return new SimpleAuthenticationInfo(users, users.getPwd(),"");
        }
    }
    2.创建DefaultWebSecurityManager对象并将realm对象和DefaultWebSecurityManager进行关联
    
    @Configuration
    public class ShiroConfig {
      
        //创建自定义的realm对象,将他注入到bean中
        @Bean
        public UserRealm userRealm(){
            return new UserRealm();
        }
      
        //创建DefaultWebSecurityManager并将realm对象和DefaultWebSecurityManager进行关联
        @Bean
        public DefaultWebSecurityManager getDefaultWebSecurityManager(UserRealm userRealm){
            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
            //进行关联
            securityManager.setRealm(userRealm);
            return securityManager;
        }
        
     3.创建ShiroFilterFactoryBean并将securityManager和ShiroFilterFactoryBean进行关联
        
        @Bean
        public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager){
           
           ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
            
            //设置安全管理器关联
            bean.setSecurityManager(securityManager);
    
            /**
             * shiro内置过滤器权限:
             *      onon: 无需认证就可以访问
             *      authc: 必须认证了才能访问
             *      user: 必须有记住我功能才能用
             *      perms: 对某个资源有权限才能访问
             *      role: 拥有某个权限才能访问
             * */
            Map<String, String> filterMap = new LinkedHashMap<>();
    
            //授权:设置权限拦截
            filterMap.put("/user/add","perms[user:add]");
            //设置跳转未授权页面的请求路径
            bean.setUnauthorizedUrl("/unauthorized");
    
            /*
            设置请求拦截
            filterMap.put("/user/add","authc");
            filterMap.put("/user/update","authc");*/
            filterMap.put("/user/*","authc");
            
            //将拦截配置放入bean
            bean.setFilterChainDefinitionMap(filterMap);
    
            //设置登陆请求路径
            bean.setLoginUrl("/index");
    
            return bean;
        }
    
    }

    5.流程

    6.shiro方法

    1.获取当前用户

    Subject currentUser=SecurityUtils.getSubject();
        
        currentUser,getPrincipal();//获得当前用户的信息
        
        currentUser.hasRole(“角色名称”);//判断是否有这个角色
        
        currentUser.isPermitted(“权限”);//判断是否有这个权限
        
        currentUser.logout();//注销

    2.向当前用户的shiro的session中存取

    Session session=currentUser.getSession();
        
        session.setAttribute("键","值");
        
        String value=(String)session.getAttribute(”键“);

      SecurityUtils.getSubject().getPrincipal();

    3.判断当前用户是否被认证

    currentUser.isAuthenticated();//被认证返回true

    4.根据账号密码生成token

    UsernamePasswordToken token=new UsernamePasswordToken(账号,密码);//生成token
        
    token.setRememnerMe(true);//设置token记住当前用户

    5.执行登陆操作

    currentUser.login(token);
  • 相关阅读:
    git创建一个空的版本库
    程序后台服务启动,MongoDB未启动(启动较慢)/(关机重启情况下)。
    启动客户端后台服务
    客户端后台服务(已注册机器)RabbitMQ未消费的情况
    MongoDB数据重复解决方案
    github中新建一个branch(分支)
    MES-后台服务卸载
    linux 第八章 高级键盘
    socketserver
    jmeter发送邮件的模板
  • 原文地址:https://www.cnblogs.com/HQ0422/p/12564413.html
Copyright © 2011-2022 走看看