//小人

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);

 

posted @ 2020-03-25 10:30  H_Q  阅读(197)  评论(0编辑  收藏  举报