美文网首页
shiro的工作原理

shiro的工作原理

作者: 晚安多巴胺 | 来源:发表于2017-11-30 19:09 被阅读0次

简述:用户通过subject登陆,形成一个UsernamePasswordToken,令牌,在域realm里完成认证、授权,成功后加入缓存。(realm可以写、也可以用默认的,也可以写很多个域)

image

快速入门

登陆顺序

1、获取登录凭证

//1 创建安全管理器
SecurityManager manager = new IniSecurityManagerFactory("classpath:shiro.ini").getInstance();
//2 绑定SecurityManager到SecurityUtils
SecurityUtils.setSecurityManager(manager);
//3 封装用户名和密码成为一个登录令牌(通行证)
UsernamePasswordToken token=new UsernamePasswordToken("用户名","密码");

2、提交凭证

//4 登录校验
Subject subject = SecurityUtils.getSubject();//获取用户实体(例如从数据库,或者ini配置文件)

3、处理登录结果

try {
    subject.login(token);
} catch ( UnknownAccountException uae ) { 
} catch ( IncorrectCredentialsException ice ) { 
} catch ( LockedAccountException lae ) { 
} catch ( ExcessiveAttemptsException eae ) { 
} 
} catch ( AuthenticationException ae ) {
}

1、登录

SecurityManager manager = new IniSecurityManagerFactory("classpath:shiro.ini").getInstance();
SecurityUtils.setSecurityManager(manager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token=new UsernamePasswordToken("用户名","密码");
subject.login(token);
 token.setRememberMe(true);//记住我,必须使用user过滤器(登陆或记住我),这里不能用authc(登陆)

2、实际身份认证

subject委托给securityManager,调用securityManager.login(token)

3、认证

SecurityManager接收令牌并简单地委托给realm

4、认证策略

如果有多个Realm身份认证,通过认证策略来决定如何认证

5、Realm认证

realm中有两个方法,这里是最终提供认证与授权的逻辑的地方

  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username= (String) principalCollection.getPrimaryPrincipal();
        //根据username取userId
        Long id = service.selectId(username);
        //根据userID取roleId
        List<Long> rid = userRoleService.selectId(id);
        //根据rid取role
        Set<String>roleNamelist=new HashSet<String>();
        //根据rid取resourceId
        List<Long> reid=new ArrayList<Long>();
        for (Long r:rid) {
            Role role = roleService.selectById(r);
            roleNamelist.add(role.getName());
            List<Long> reid1 = roleResourceService.selectId(r);
            for (Long rei: reid1) {
                reid.add(rei);
            }

        }
        //根据resourceID取resourceUrl
        Set<String> setUrl=new HashSet<String>();
        for (Long reid2:reid) {
            String s = resourceService.selectUrlById(reid2);
            if (s!=null){
                setUrl.add(s);
            }

        }
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setRoles(roleNamelist);//添加角色
        info.addStringPermissions(setUrl);//添加权限
        return info;
    }

    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String username= (String) authenticationToken.getPrincipal();

        User user = service.selectOne(new EntityWrapper<User>(new User(username)));

        return new SimpleAuthenticationInfo(user.getLogin_name(),user.getPassword(), ByteSource.Util.bytes(salt),getName());

    }
}

spring-shiro配置模板

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--创建shiroFilter,shiro的核心-->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!--注入securityManager-->
        <property name="securityManager" ref="securityManager"/>
        <!--如果没有认证,自动跳转到该页面-->
        <property name="loginUrl" value="/login"/>
        <!--过滤链-->
        <property name="filterChainDefinitions">
            <value>
                /login*=anon
                /commons/**=anon
                /front/**=anon
                /static/**=anon
                /** = user<!--authc要登陆才能用,user只要登录过就可以-->
            </value>
        </property>
    </bean>

    <!--配置WebSecurityManager-->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <!--注入自定义的realm-->
        <property name="realm" ref="userRealm"/>
        <!--缓存-->
        <property name="cacheManager" ref="cacheManager"/>
    </bean>

    <!--自定义reelm,用来认证和授权-->
    <bean class="com.study.shiro.UserRealm" id="userRealm">
        <property name="credentialsMatcher" ref="credentialsMatcher"/>
        <property name="authenticationCachingEnabled" value="true"/>
        <property name="authenticationCacheName" value="authenticationCache"/>
        <property name="authorizationCacheName" value="authorizationCache"/>
    </bean>

    <!--凭证匹配器,用来解密md5-->
    <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher" id="credentialsMatcher">
        <property name="hashAlgorithmName" value="md5"/>
    </bean>

    <!--生命周期-->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    <!--换村-->
    <bean class="org.apache.shiro.cache.ehcache.EhCacheManager" id="cacheManager">
        <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>
    </bean>
    <bean class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager" id="sessionManager">
        <property name="sessionDAO" ref="sessionDAO"/>
        <!--设置全局会话超时时间 -->
        <property name="globalSessionTimeout" value="#{30 * 60 * 1000}"/>
        <!--URL上带sessionID 默认为true-->
        <property name="sessionValidationSchedulerEnabled" value="false"/>
    </bean>
    <bean class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO" id="sessionDAO">
        <property name="activeSessionsCacheName" value="activeSessionCache"/>
    </bean>
</beans>

在webxml里的配置

<filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <init-param>
            <param-name>targetFilterLifecycle</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

相关文章

  • shiro的工作原理

    简述:用户通过subject登陆,形成一个UsernamePasswordToken,令牌,在域realm里完成认...

  • shiro原理之过滤器

    Shiro原理-过滤器 前言 这几天一直在研究Shiro到底是如何工作的,即一个请求过来了,它是如何做到知道这个请...

  • shiro原理

    shiro原理 Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能,是目前用得比较...

  • shiro原理

    框架解释: subject:主体,可以是用户也可以是程序,主体要访问系统,系统需要对主体进行认证、授权。 secu...

  • shiro原理简析+基于springboot基础实践

    1、shiro原理简析 原理简析: 1、subject支持不通调用获取用户信息 2、SecurityManager...

  • 学习shiro笔记

    工作需要,学习shiro。阅读张开涛的Shiro教程 AuthenticationInfo作用

  • shiro原理分析

    1、shiro如何介入你的spring程序基本流程是 调用FilterRegistrationBean向sprin...

  • 《跟我学Shiro》学习笔记 第二章:身份验证

    前言 上一章主要对Shiro功能,运行原理,架构设计进行了介绍,这一章我们主要学习Shiro的身份验证。本章的代码...

  • shiro反序列化的复现

    搭建环境:云服务器 ubuntu18.0.4漏洞的原理:shiro默认使用了CookieRememberMeMan...

  • shiro原理之认证

    前言 这几天因为项目要用到鉴权,很久以前就听说过shiro了,但是之前一直要求用的是Spring Security...

网友评论

      本文标题:shiro的工作原理

      本文链接:https://www.haomeiwen.com/subject/kdjvbxtx.html