深入理解Shiro(下)

简介: 深入理解Shiro(下)

关键代码详解



首先,我们导入以来完成后,需要进行配置自定义配置shiro类,同时用@Configuration注解标注

@Configuration
//自定义配置类,实现shiro的配置
public class shiroConfig{
  //1. shiroFilterFactoryBean
        //2. DefaultWebSecurityManager 安全管理器(关联Realm)
        //3. 创建realm对象
}

在shiro配置类中有三个内置类是十分重要的,他们分别是


  • ShiroFilterFactoryBean
  • DefaultWebSecurityManager
  • realm对象


他们决定了shiro的工作机制及流程


shiro006.png


如图所示


Realm :

Realm : 作为接收需要接受的安全数据的对象,起着与我们底层的数据交互的作用,它通过封装安全数据,然后放入在Spring的容器中


//3. 创建realm对象,需要自定义类,然后交给spring托管(放到bean中)
@Bean(name = "userRealm")
public UserRealm userRealm(){
    return new UserRealm();
}


DefaultWebSecurityManager :


DefaultWebSecurityManager : 作为安全管理员,他的作用就是来关联我们放置在容器中Realm对象,同时,将自身再封装成为Bean交给spring容器来托管,然后等待ShiroFilterFactoryBean的调用 。可以看出他是shiro的核心,相当于我们springMVC中的DispatcherServlet

//2. DefaultWebSecurityManager 安全管理器(关联Realm)
//@Qualifier("userRealm")中的内容就是下面第三步中的@Bean中name属性
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    //用securityManager来关联realm
    securityManager.setRealm(userRealm);
    //因为我们第三步已经将userRealm交给了spring接管,所以需要传参数来得到,而不是直接new
    return securityManager;
}


ShiroFilterFactoryBean :


**ShiroFilterFactoryBean : 作用就是继续关联安全管理器DefaultWebSecurityManager,然后同时将自己也封装成bean **


//1. shiroFilterFactoryBean
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
    ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
    //关联DefaultWebSecurityManager安全管理器
    bean.setSecurityManager(defaultWebSecurityManager);
    /**
     * 添加内置过滤器
     * ● anon : 无需认证即可访问
     * ● authc :必须认证才能访问
     * ● user :必须拥有记住我才能访问
     * ● perms  : 拥有对某个资源的权限才能访问
     * ● role  : 拥有某个角色权限才能访问
     */
    //拦截的请求-----------------------------------
    Map<String, String> filterMap = new LinkedHashMap<>();
    filterMap.put("/vipFirst","perms[vip1]");
    filterMap.put("/vipSecond","perms[vip2]");
    bean.setFilterChainDefinitionMap(filterMap);//他的参数是从map集合中拿的,所以需要提前设置一个集合
    //如果没有权限,设置跳转页面(登录的请求)
    bean.setLoginUrl("/login");
    //未授权的请求
    //bean.setUnauthorizedUrl("");
    //-------------------------------------------
    return bean;
}


他的拦截请求会通过一个map集合来操作,但是shiro也存在很多的内置过滤器 , 通过这些过滤器,我们就可以实现请求过滤操作


* ● anon : 无需认证即可访问

* ● authc :必须认证才能访问

* ● user :必须拥有记住我才能访问

* ● perms  : 拥有对某个资源的权限才能访问

* ● role  : 拥有某个角色权限才能访问


在ShiroFilterFactoryBean中我们可以做很多需要的操作比如:


  • 请求的拦截
  • 未授权用户页面的跳转
  • ….


上述三者的执行顺序虽然是从:S - > D - > R (简写)


但是我们在按逻辑写的时候确实 从 : R- > D -> S


对外核心Subject


与应用程序的代码直接进行交互的对象就是Subject, 它代表的是当前用户,这个用户不仅仅值得是一个具体的人,而是与当前应用交互的任何事物。与Subject进行交互,他就会将所有的东西全都委托给我们的安全管理员(DefaultWebSecurityManager ),他才是真正的执行者。


对内核心Realm


为什么这里我将他作为对内核心,因为我们所有需要进行安全操作的事情都在他的实现类中完成


//3. 创建realm对象
    //实现的两个方法就是 springsecurity中授权和认证
public class UserRealm extends AuthorizingRealm {
  //认证
   // ....
    //授权
}

比如:


  • 对用户进行授权
  • 认证
  • 密码保护


认证


//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("===> 执行了认证方法");
        //获取当前的令牌,及其其中的信息
        UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;
        // 获取当前的用户 , 封装用户的登录数据(在controller的登录方法中实现)
        User user = userService.selectUser(userToken.getUsername());
        //判断是否与数据库中的相同,如果不相同
        if (!user.getUsername().equals(userToken.getUsername())){
            return null; //就会抛出异常
        }
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();
        session.setAttribute("loginUser",user);
        //密码认证, shrio来帮助我们实现
        AuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),user.getDept());
        return info;
    }


授权


//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("===> 执行了授权方法");
        //执行授权的功能
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        //将用户所具有的权限存放在数据库中,然后登录时获取用户的全部信息
        Subject subject = SecurityUtils.getSubject();
        //在用户进行认证时我们进行这个操作【AuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),user.getDept());】
        //通过他我们就可以拿到数据
        User user = (User) subject.getPrincipal();
        //设置当前用户的权限
        authorizationInfo.addStringPermission(user.getDept());
        //authorizationInfo.addRole("vip1");
        return authorizationInfo;
    }
目录
相关文章
|
存储 JSON 前端开发
Shiro实现记住我(十)
Shiro实现记住我(十)
428 0
Shiro实现记住我(十)
|
安全 测试技术 API
Shiro详解
Shiro详解
121 0
|
安全 Java 测试技术
深入理解Shiro(上)
深入理解Shiro(上)
85 0
|
安全 Java 数据库连接
Shiro 中的 Realm
Shiro 中的 Realm
116 0
|
存储 缓存 安全
|
消息中间件 JavaScript 小程序
再见了 shiro
再见了 shiro
|
消息中间件 安全 JavaScript
再见了 shiro !
再见了 shiro !
|
缓存 安全 前端开发
|
存储 安全 Java
shiro(二)shiro详解(2)
shiro(二)shiro详解
180 0
shiro(二)shiro详解(2)
|
Java 数据安全/隐私保护
shiro(二)shiro详解(1)
shiro(二)shiro详解
248 0
shiro(二)shiro详解(1)