精华内容
下载资源
问答
  • shiro学习

    2017-06-23 10:34:23
    后台的安全框架,基本就两种,要么用的是shiro来管理,要么就是spring security,自己现在先开始学习shiro,这里就一点一点分享一下自己的学习过程,当然自己现在也是参考网上的相关技术文献,最后还是自己用代码...

    一直以来,对于Java开发来说,后台的安全框架,基本就两种,要么用的是shiro来管理,要么就是spring security,自己现在先开始学习shiro,这里就一点一点分享一下自己的学习过程,当然自己现在也是参考网上的相关技术文献,最后还是自己用代码实现一下,这样才能学习认识的更加深刻,废话不说了,过程如下:

    1.shiro的身份认证

    第一步:收集主体提交的身份和凭证; 

    我们使用UsernamePasswordToken,支持最常用的用户名/密码认证方式。这是Shiro的org.apache.shiro.authc.AuthenticationToken接口,这是由Shiro的认证系统代表提交的主体和凭证使用的基本接口的实现。username和password就是和Subject认证主体中对应的身份和凭证做验证的。
    第二步:提交该身份和凭证; 

    通过SecurityUtils工具类获取当前执行的用户,然后进行身份认证,参考Subject主体,数据库查询出来的信息。
    第三步 :如果提交成功,允许访问,否则重新尝试身份验证或阻止访问;

    根据认证的结果来处理正确或者错误的结果,所以我们需要将currentUser.login(token)使用try/catch包起来

    第四步:退出

    与认证相反的是释放所有已知的确定的状态。当主体完成与应用程序交互,可以调用subject.logout()放弃所有的身份信息,subject.logout()会删除所有身份信息以及他们的会话(这里的会话指的是Shiro中的会话)。

    2.shiro的权限认证,即授权

    权限认证,也就是访问控制,即在应用中控制谁能访问哪些资源。在权限认证中,最核心的三个要素是:权限,角色和用户:
    权限(permission)即操作资源的权利,比如访问某个页面,以及对某个模块的数据的添加,修改,删除,查看的权利;
    角色(role):指的是用户担任的的角色,一个角色可以有多个权限;

    用户(user): 在Shiro 中,代表访问系统的用户,即上一篇博文提到的Subject认证主体。

    2.1 基于角色的访问控制

      也就是说,授权过程是通过判断角色来完成的,哪个角色可以做这件事,哪些角色可以做这件事等等。它有如下API:

    方法 作用
    hasRole(String roleName) 判断是否有该角色访问权,返回boolen
    hasRoles(List<String> roleNames) 判断是否有这些这些角色访问权,返回boolean[]
    hasAllRoles(Collection<String> roleNames) 判断是否有这些这些角色访问权,返回boolean

      对这三个API,做一下简单的说明,第一个很简单,传入一个role即可,判断是否拥有该角色访问权,第二个方法是传入一个role的集合,然后Shiro会根据集合中的每一个role做一下判断,并且将每次的判断结果放到boolean[]数组中,顺序与集合中role的顺序一致;第三个方法也是传入一个role的集合,不同的是,返回boolean类型,必须集合中全部role都有才为true,否则为false。

    除了这三个API外,Shiro还提供了check的API,与上面不同的是,has-xxx会返回boolean类型的数据,用来判断,而check-xxx不会返回任何东西,如果验证成功就继续处理下面的代码,否则会抛出一个异常,可以用来通过捕获异常来处理。API如下:

    方法 作用
    checkRole(String roleName) 如果判断失败抛出AuthorizationException异常
    checkRoles(String... roleNames) 如果判断失败抛出AuthorizationException异常
    checkRoles(Collection<String> roleNames) 如果判断失败抛出AuthorizationException异常

    2.2 基于权限的访问控制

      基于权限的访问控制和基于角色的访问控制在原理上是一模一样的,只不过API不同而已,我不再做过多的解释,API如下:

    方法 作用
    isPermitted(String perm) 判断是否有该权限,返回boolen
    isPermitted(List<String> perms) 判断是否有这些这些权限,返回boolean[]
    isPermittedAll(Collection<String> perms) 判断是否有这些这些权限,返回boolean
    checkPermission(String perm) 如果判断失败抛出AuthorizationException异常
    checkPermissions(String... perms) 如果判断失败抛出AuthorizationException异常
    checkPermissionsAll(Collection<String> perms) 如果判断失败抛出AuthorizationException异常

    3.Shiro的内置过滤器(Default Filters)

    Shiro中内置的过滤器有以下几个:

    过滤器名 对应的类
    anon(匿名) org.apache.shiro.web.filter.authc.AnonymousFilter
    authc(身份验证) org.apache.shiro.web.filter.authc.FormAuthenticationFilter
    authcBasic(http基本验证) org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
    logout(退出) org.apache.shiro.web.filter.authc.LogoutFilter
    noSessionCreation(不创建session) org.apache.shiro.web.filter.session.NoSessionCreationFilter
    perms(许可验证) org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
    port(端口验证) org.apache.shiro.web.filter.authz.PortFilter
    rest(rest方面) org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
    roles(权限验证) org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
    ssl(ssl方面) org.apache.shiro.web.filter.authz.SslFilter
    user(用户方面) org.apache.shiro.web.filter.authc.UserFilter

      这些内置的过滤器使用方法是这样的,一般先指定一个请求url对应一个过滤器名,由于该过滤器对应一个类,而这个类中会有一个属性,这个属性是当验证失败的时候指定要跳转到那个url的,所以将这个属性配置成验证失败后你要请求的url即可。

    我简单说明一下这个配置,比如定义的authc.loginUrl=/login,authc是一个内置过滤器,它对应org.apache.shiro.web.filter.authc.AnonymousFilter类,而这个类中有个loginUrl属性,表示验证失败后将要请求的url映射,这个url映射与一个具体的servlet对应,读到这里,可以和上面的servlet配置对比一下就知道了。roles.unauthorizedUrl也是一样的道理,只不过这里验证失败直接请求一个具体的jsp页面而已。

    [users]中是Subject认证主体,就不再赘述了,[urls]中定义需要拦截哪些请求,并做什么验证。比如/login的url映射请求不拦截,因为是登陆的,请求/admin的url映射的话做身份认证,请求/student的url映射的话要做角色认证,且必须是teacher角色才行,请求/teacher的url映射的话需要进行权限认证,必须有user:create权限的用户才可以通过验证。

    2.3   url匹配方式

    /admin?=authc,表示可以请求以admin开头的字符串,如xxx/adminfefe,但无法匹配多个,即xxx/admindf/admin是不行的 
    /admin*=authc表示可以匹配零个或者多个字符,如/admin,/admin1,/admin123,但是不能匹配/admin/abc这种 
    /admin/**=authc表示可以匹配零个或者多个路径,如/admin,/admin/ad/adfdf等。 
    /admin*/**=authc这个就不多说了,结合上面两个就知道了。


    展开全文
  • 所以之前用到shiro还是更多一点。但是后面由于SpringBoot的成熟他和SpringSecurity整合起来更加的方便,所以SpringSecurity也开始流行了起来。 二、原理 有以下三点 授权 认证 攻击防护 其核心就是一组过滤器...

    一 、概述

    SpringSecurity是Spring大家族的成员之一,主要是做授权和认证的。里面包括了一系列认证的逻辑和权限的控制。在没有SpringBoot之前SpringSecurity配置起来还是很麻烦的而且它看起来比shiro更加重量级。所以之前用到shiro还是更多一点。但是后面由于SpringBoot的成熟他和SpringSecurity整合起来更加的方便,所以SpringSecurity也开始流行了起来。

    二、原理

    有以下三点
    • 授权

    • 认证

    • 攻击防护

      其核心就是一组过滤器链,项目启动后将会自动配置。最核心的就是 Basic Authentication Filter 用来认证用户的身份,一个在spring security中一种过滤器处理一种认证方式。
      在这里插入图片描述

    会检查是否是一个登录请求;
    是否包含username 和 password (也就是该过滤器需要的一些认证信息) ;
    如果不满足则放行给下一个。

    下一个按照自身职责判定是否是自身需要的信息,basic的特征就是在请求头中有 Authorization:Basic eHh4Onh4 的信息。中间可能还有更多的认证过滤器。最后一环是 FilterSecurityInterceptor,这里会判定该请求是否能进行访问rest服务,判断的依据是 BrowserSecurityConfig中的配置,如果被拒绝了就会抛出不同的异常(根据具体的原因)。Exception Translation Filter 会捕获抛出的错误,然后根据不同的认证方式进行信息的返回提示。

    展开全文
  • Spring security:重量级安全框架 Apache shiro:轻量级安全框架 为什么要使用Shiro? 因为虽然重量级的功能更加强大,细粒度更高,但是它的学习难度相比较于轻量级的Shiro要高一些。虽然功能很强大,但是还是有...

    Shiro:权限框架

    Spring security:重量级安全框架
    Apache shiro:轻量级安全框架

    为什么要使用Shiro?

    因为虽然重量级的功能更加强大,细粒度更高,但是它的学习难度相比较于轻量级的Shiro要高一些。虽然功能很强大,但是还是有很多地方用不到。
    Shiro:粗粒度,学习难度低,功能够用。

    Shiro的四大基石

    身份验证(登录)
    授权(权限判断)
    密码学(加密)
    会话管理(session:任何地方都可以使用)

    宏观上来看Shiro:
    使用Shiro,Subject代表当前用户。
    Shiro SecurityManager:Shiro的权限管理器,Shiro的所有功能都要通过它,都是靠它来完成得分。
    Realm:拿取数据全靠它。获取登录用户的信息和权限。
    微观上来看Shiro:
    Shiro什么语言都支持,是不是web项目也无所谓。

    测试Shiro
    1.拿到shiro.ini配置文件,并且拿出工厂
    2、从工厂中获取到SecurityManager对象
    3、把SecurityManager对象设置到上下文中
    4、获取到当前用户(如果没有登录就是游客)
    5、如果用户没有登录。我们就要让它登录
    6、要想登录,就要先准备令牌:
    7、根据令牌来实现登录。
    8、退出系统。

    public class HelloShiro {
        @Test
        public void myTest() throws Exception{
    //        1、获取到最重要的那个对象,SecurityManager
    //        2、读取到Shiro.ini的配置文件,并且拿到工厂
            Factory<SecurityManager> factory  = new IniSecurityManagerFactory("classpath:shiro.ini");
    //      从工厂里面拿到SecurityManager对象
            SecurityManager securityManager = factory.getInstance();
    //        把SecurityManager对象设置到上下文里面
    //        将它放到一个地方,然后所有的位置都可以调用
            SecurityUtils.setSecurityManager(securityManager);
    //        获取到当前用户,没有登录那就是游客访问
            Subject currentUser = SecurityUtils.getSubject();
            System.out.println("是否登录成功:"+currentUser.isAuthenticated());
    //如果用户没有登录,就要让他登录
            if(!currentUser.isAuthenticated()){
                try {
    //            使用户登录,先准备令牌
                    UsernamePasswordToken token = new UsernamePasswordToken("guest", "guest");
    //        根据令牌来实现登录
                    currentUser.login(token);
                } catch (AuthenticationException e) {
                    e.printStackTrace();
                    System.out.println("出现了一个未知错误");
                }
            }
            //角色判断
            System.out.println("我是一个admin角色的人:"+currentUser.hasRole("admin"));
            System.out.println("我是一个it角色的人:"+currentUser.hasRole("it"));
    
            //权限判断
            System.out.println("我有employee:save的权限:"+currentUser.isPermitted("employee:save"));
            System.out.println("我有employee:delete的权限:"+currentUser.isPermitted("employee:delete"));
            System.out.println("我有employee:update的权限:"+currentUser.isPermitted("employee:update"));
            System.out.println("我有department:update的权限:"+currentUser.isPermitted("department:update"));
    
            //System.out.println("是否登录成功:"+currentUser.isAuthenticated());
            //退出系统
            //currentUser.logout();
            //System.out.println("是否登录成功:"+currentUser.isAuthenticated());
        }
    }
    
    

    未知账号异常
    UnknownAccountException
    不正确密码异常
    IncorrectCredentialsException

    定义一个自己的Realm,根据自己想要的效果来完成功能。

    package cn.cxm.shiro;
    
    import org.apache.shiro.authc.*;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.authz.SimpleAuthorizationInfo;
    import org.apache.shiro.realm.AuthorizingRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    import org.apache.shiro.util.ByteSource;
    
    import java.util.HashSet;
    import java.util.Set;
    
    //自定义Realm,按照自己想要的效果来完成功能
    //自定义Realm一般直接继承AuthorizingRealm接口,因为里面包含了身份认证和授权两个方法
    public class MyRealm extends AuthorizingRealm{
    //    获取到这个Realm的名称
        @Override
        public String getName(){
            return "MyRealm";
        }
    
    //    必须是登录成功进来的,拿到用户名,根据用户名去到数据库里面拿到对应的角色与权限
    //    授权验证的方法
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            //1.拿到当前用户名
            // 拿出当前登录用户的主体,也就是用户名
            String principal = (String) principalCollection.getPrimaryPrincipal();
            //2.根据用户名拿到对应的角色与权限
            Set<String> roles = getRoles(principal);
            Set<String> perms = getPerms(principal);
    
            //3.返回对应的对象
            SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
            authorizationInfo.setRoles(roles);
            authorizationInfo.setStringPermissions(perms);
    
            return authorizationInfo;
        }
    
        //模拟根据用户名拿到对应的角色与权限
        private Set<String> getRoles(String username){
            Set<String> roles = new HashSet<String>();
            roles.add("admin");
            roles.add("it");
            return roles;
        }
        private Set<String> getPerms(String username){
            Set<String> perms = new HashSet<String>();
            perms.add("employee:save");
            perms.add("employee:delete");
            perms.add("employee:*");
            perms.add("*");
            return perms;
        }
    
    
    //   登录验证(身份验证)
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
            //1.拿到令牌(用户名密码Token)
            UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
            //2.拿到用户名,这里的用户名是传过来的
            String username = token.getUsername();
            //3.根据用户名到数据库进行查询
            //  这个密码是数据库的密码
            String password = getByName(username);
            if(password==null){
                //返回空就是代表用户名不存在,shior会自动帮我们报UnknownAccountException
                return null;
            }
    //        在这里添加盐值,通过ByteSource来添加盐值
            ByteSource salt = ByteSource.Util.bytes("cxm");
            //4.我们把值传进去,它会自己帮我们判断密码
            //  传的是数据库密码:它要把这个密码和令牌中的密码做对象,如果对应不上,就会报:IncorrectCredentialsException
    //       将盐值添加到下面
            SimpleAuthenticationInfo authenticationInfo
                    = new SimpleAuthenticationInfo(username,password,salt,getName());
            return authenticationInfo;
        }
    
        //模拟根据当前登录用户拿到密码
        private String getByName(String username){
            if("root".equals(username)){
                return "282e4ced1f2b6fe522107c5051d27450";
            }else if("guest".equals(username)){
                return "guest";
            }
            return null;
        }
    }
    
    

    快捷键:Ctrl+T,可以看到子类

    密码加密功能

    MD5加密
    验证加密的密码:
    使用加密凭证匹配器

    //      设置Realm的密码匹配器
    //        new一个密码匹配器
            HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
    //        定义密码算法
            matcher.setHashAlgorithmName("MD5");
    //        定义加密次数
            matcher.setHashIterations(10);
            myRealm.setCredentialsMatcher(matcher);
    //      在这里我们没有办法添加盐值,需要到MyRealm里面才能添加
    

    配置盐值

    匹配器里面只有加密的方式和次数
    盐值设置不设置早匹配器里面,而是设置在Realm里面。

    //        在这里添加盐值,通过ByteSource来添加盐值
            ByteSource salt = ByteSource.Util.bytes("cxm");
            //4.我们把值传进去,它会自己帮我们判断密码
            //  传的是数据库密码:它要把这个密码和令牌中的密码做对象,如果对应不上,就会报:IncorrectCredentialsException
    //       将盐值添加到下面
            SimpleAuthenticationInfo authenticationInfo
                    = new SimpleAuthenticationInfo(username,password,salt,getName());
            return authenticationInfo;
    

    Shiro集成Spring

    把核心对象(SecurityManager)交给Spring创建,MyRealm也交给Spring创建。
    将我们的aisell项目备份后导入,
    然后导包。

        <!-- shiro的支持包 -->
        <dependency>
          <groupId>org.apache.shiro</groupId>
          <artifactId>shiro-all</artifactId>
          <version>1.4.0</version>
          <type>pom</type>
        </dependency>
        <!-- shiro与Spring的集成包 -->
        <dependency>
          <groupId>org.apache.shiro</groupId>
          <artifactId>shiro-spring</artifactId>
          <version>1.4.0</version>
        </dependency>
    

    在web.xml里面配置Shiro过滤器。

    Shiro的过滤器可以拦截所有的请求。
    DelegatingFilterProxy,这个过滤器什么功能都没有,他什么也不做,真正的过滤功能是在Spring中的过滤器里面完成的。是J2EE的原生过滤器,它将代码拦截以后,交给Spring来处理。

      <!-- Spring与shiro集成:需要定义一个shiro过滤器(这是一个代理过滤器,它会到spring的配置中找一个名称相同的真实过滤器) -->
      <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>
    

    配置applicationContext-shiro.xml,并在applicationContext.xml里面读取shiro的配置文件。
    配置applicationContext-shiro.xml

    <?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-3.0.xsd">
    
        <!-- securityManager:Spring创建核心对象 -->
        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <!-- 配置一个realm,到数据库中获取权限数据 -->
            <property name="realm" ref="aiSellRealm"/>
        </bean>
        <!-- 2.我们可以自定义一个realm这个必需实现org.apache.shiro.realm.Realm接口 -->
        <bean id="aiSellRealm" class="cn.cxm.aisell.shiro.AiSellRealm">
            <property name="credentialsMatcher">
                <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                    <property name="hashAlgorithmName" value="MD5"/>
                    <property name="hashIterations" value="10" />
                </bean>
            </property>
        </bean>
    
        <!-- 3.lifecycleBeanPostProcessor:可以自动调用在Spring Ioc窗口中 Shiro bean的生成周期方法 -->
        <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
        <!-- 4.启动ioc容器中使用 shiro的注解,但是必需配置在Spring Ioc容器中Shiro bean的生成周期方法 -->
        <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
              depends-on="lifecycleBeanPostProcessor"/>
        <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
            <property name="securityManager" ref="securityManager"/>
        </bean>
    
        <!-- 5.shiro的真实过滤器(注:这个名称必需和web.xml的代表过滤器【DelegatingFilterProxy】名称一样) -->
        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager"/>
            <!-- 登录的url,如果没有登录成功,你访问的路径会跳到这个页面 -->
            <property name="loginUrl" value="/s/login.jsp"/>
            <!-- 登录成功的url,如果登录成功,会跳转到这个页面 -->
            <property name="successUrl" value="/s/main.jsp"/>
            <!-- 没有权限时跳转到这个位置 -->
            <property name="unauthorizedUrl" value="/s/unauthorized.jsp"/>
            <!--
                下面是在配置哪些资源被保护,哪些资源需要权限
                anon:不需要登录也可以访问相应的权限
                authc:需要权限才能访问
                /** :所有文件及其子文件
                路径 = perms[权限]
                /employee/index = perms[employee:index]
            -->
            <!--这里的权限是固定的,假如要放开很多路径的权限,就要写很多,不方便,所以不用-->
            <!--<property name="filterChainDefinitions">
                <value>
                    /s/login.jsp = anon
                    /s/main.jsp = anon
                    /s/unauthorized.jsp = anon
                    /** = authc
                </value>
            </property>-->
            <!--使用下面的方法-->
            <property name="filterChainDefinitionMap" ref="filterChainDefinitionMapBuilderMap" />
        </bean>
        <!--最后的结果就是对应方法返回的Map值-->
        <bean id="filterChainDefinitionMapBuilderMap" factory-bean="filterChainDefinitionMapBuilder"
              factory-method="createFilterChainDefinitionMap" />
        <!--配置相应的bean-->
        <bean id="filterChainDefinitionMapBuilder" class="cn.cxm.aisell.shiro.FilterChainDefinitionMapBuilder" />
    </beans>
    
    
    <!--引入shiro的配置-->
        <import resource="classpath:applicationContext-shiro.xml"/>
    

    web.xml里面配置的shiro过滤器名字必须和applicationContext-shiro.xml里面的真正的shiro过滤器名字一样。

     <!-- 5.shiro的真实过滤器(注:这个名称必需和web.xml的代表过滤器【DelegatingFilterProxy】名称一样) -->
        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager"/>
            <!-- 登录的url,如果没有登录成功,你访问的路径会跳到这个页面 -->
            <property name="loginUrl" value="/s/login.jsp"/>
            <!-- 登录成功的url,如果登录成功,会跳转到这个页面 -->
            <property name="successUrl" value="/s/main.jsp"/>
            <!-- 没有权限时跳转到这个位置 -->
            <property name="unauthorizedUrl" value="/s/unauthorized.jsp"/>
    

    获取Map过滤

    package cn.cxm.aisell.shiro;
    
    import java.util.LinkedHashMap;
    
    //这个方法是用来定义权限的,哪些路径放行,哪些路径不放行,在这里来写
    public class FilterChainDefinitionMapBuilder {
    //使用集合,将需要放行的路径,需要权限的路径,需要登录访问的路径放进去
        public LinkedHashMap<Object, Object> createFilterChainDefinitionMap(){
            LinkedHashMap<Object, Object> filterChainDefinitionMap = new LinkedHashMap<>();
    //        设置不需要访问也可以被放行的路径
            filterChainDefinitionMap.put("/s/login.jsp", "anon");
            filterChainDefinitionMap.put("/login", "anon");
            //需要权限才能访问的路径
            filterChainDefinitionMap.put("/employee/index", "perms[employee:index]");
    //        设置需要登录才能被放行的路径
            filterChainDefinitionMap.put("/**", "authc");
    
            return filterChainDefinitionMap;
        }
    }
    
    
    展开全文
  • shiro框架解读

    2020-07-17 00:37:05
    扩展性非常强,灵活性高,是一个不错的优秀开源框架,通过阅读源码,运用到一些设计模式,还是挺值得去学习的。 shiro框架图 Subject 主体:可以是当前的用户,可以是第三方服务。 Security Manager 安全管理器:...

    最近看了一下shiro源码,觉得shiro做有关权限系统挺方便的,很多的东西它都是默认了的,根据实际情况重写一些方法,便可应用到实际开发中。扩展性非常强,灵活性高,是一个不错的优秀开源框架,通过阅读源码,运用到一些设计模式,还是挺值得去学习的。

    shiro框架图

    在这里插入图片描述
    Subject 主体:可以是当前的用户,可以是第三方服务。
    Security Manager 安全管理器:负责协调各个组件的。
    Authenticator:登录认证器,登录时用到。
    Authorizer:权限认证器,当访问的资源需要权限校验时会调用。
    realm:使用shiro框架登录与鉴权时,一定要至少配置一个realm,实现其中的那个两个方法,一个是身份信息(AuthenticationInfo)封装返回,一个是权限信息(AuthorizationInfo)封装返回。

    shiro登录校验流程及权限校验流程

    在这里插入图片描述
    登记认证时可以通过FormAuthenticationFilter进行验证,也可以直接通过subje.login(token),其实FormAuthenticationFilter在做检验时,间接调用了subje.login(token)方法进行权限校验。

    shiro cookie信息创建

    //shiro中创建cookie信息
    AbstractNativeSessionManager:
    public Session start(SessionContext context) {
       Session session = this.createSession(context); //创建simpleSession
         this.applyGlobalSessionTimeout(session);
         this.onStart(session, context);
         this.notifyStart(session);//通知
         return this.createExposedSession(session, context);
     }
     
    DefaultWebSessionManager:
    protected void onStart(Session session, SessionContext context) {
        super.onStart(session, context);
        if (!WebUtils.isHttp(context)) {
            log.debug("SessionContext argument is not HTTP compatible or does not have an HTTP request/response pair. No session ID cookie will be set.");
        } else {
            HttpServletRequest request = WebUtils.getHttpRequest(context);
            HttpServletResponse response = WebUtils.getHttpResponse(context);
            if (this.isSessionIdCookieEnabled()) {
                Serializable sessionId = session.getId();
                this.storeSessionId(sessionId, request, response);//将sessionid保存到cookie
            } else {
                log.debug("Session ID cookie is disabled.  No cookie has been set for new session with id {}", session.getId());
            }
    
            request.removeAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE);
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_IS_NEW, Boolean.TRUE);
        }
    }
    
    展开全文
  • SpringMVC - Shiro 整合

    2016-12-09 13:01:46
    目前,使用Apache Shiro的人越来越多,因为它相当简单,对比spring Security,可能没有Spring Security做的功能强大,但是在实际工 作时可能并不需要那么复杂的东西,所以使用小而简单的Shiro就足够了。对于它俩...
  • spring-boot整合shiro

    万次阅读 2018-10-06 02:30:27
    最近项目中也需要用到权限验证功能,项目为spring-boot工程,现成的权限验证框架有shiro和spring-securityshiro相对spring-security来说学习难度要低一点,也是老牌成熟的产品,因此选择shiro...
  • Shiro反序列化漏洞

    千次阅读 2020-06-01 22:54:44
    java中的权限框架有SpringSecurityShiro,由于Spring功能强大但复杂,Shiro的简单强大,扩展性好因此用的还是很多。 1.2 漏洞原理   Apache Shiro框架提供了记住我的功能(RememberMe),用户登录成功后会生成...
  • shiro的hello world

    2016-04-03 22:04:58
    shiro 安全框架小型而且来说很好用,想比较spring的安全security来讲要简单很多,当然 看开涛老师的博客也能到很多,当然看海涛老师的博客,个人觉得还是比较乱,当然当你熟悉了shiro在查看开涛老师的shiro进行...
  • 大家好,今天给大家分享一个权限管理的框架Apache的Shiro,说实话本来我是...不过后来发现公司的项目使用的是Apache的Shiro,本着学以致用的原则,就先学Shiro,等以后有机会了Spring Security还是会分享给大家...
  • 还是深度绑定spring,较慢性能,学习曲线陡峭的spring security,或多或少都不是我们的理想型。 于是乎sureness诞生了,我们希望能解决这些,提供一个面向restful api,无框架依赖,可以动态修改权限,多认证策略,...
  • SpringCloud-Security底层基于spring security,市面流行的还是shiro。它是一个安全框架,它提供一组可以在Spring上下文中配置Bean,充分利用Spring IOC,DI和AOP功能,为应用提供声明式安全访问控制功能。 (2)...
  • 欢迎光顾我的博客 开端 好的,起因是我把最近做好的项目给一部分人进行了测试,发现大部分朋友都提出了同一个问题,你的系统权限管理是如何...而对于权限控制的框架呢,听的最多的还是 Shiro 还有 Spring Security。Sp
  • 最近项目中也需要用到权限验证功能,项目为spring-boot工程,现成的权限验证框架有shiro和spring-securityshiro相对spring-security来说学习难度要低一点,也是老牌成熟的产品,因此选择shiro作为项目...
  • 欢迎关顾我的博客 开端 好的,起因是我把最近做好的项目给一部分人进行了测试,发现大部分朋友都提出了同一个问题,你的系统权限管理是如何...而对于权限控制的框架呢,听的最多的还是 Shiro 还有 Spring Security。Sp
  •  关于shiro框架,我还是从飞机哪里听来的,就连小贱都知道,可我母鸡啊。简单百度了下,结论很好上手,比spring的security要简单许多...于是我就是开始了我的shiro学习之路 。正巧这几天在研究spring-boot集成...
  • 开端 好的,起因是我把最近做好的项目给一部分人进行了测试,发现大部分朋友都提出了同一个问题,你的系统权限管理是如何实现...而对于权限控制的框架呢,听的最多的还是 Shiro 还有 Spring Security。Spring 的安全框
  • Spring Security

    千次阅读 2016-01-17 13:00:35
    安全及权限控制是每个应用难以绕开的部分,这部分业务也不是特别复杂,但是我想这块业务具有通用性的特点,既然有开源的框架,完全可以拿来... Web开发中,安全框架Spring Security和Apache Shiro比较主流,虽然Shiro
  • Spring Boot Security 权限 这两天研究了一下权限管理框架。...而这两天的学习中,就我自己的体会而言,学习Spring Security还是有一定难度的。虽然它的扩展性非常的好,我们可以重载它默认的类,重写方法...
  • Spring-security整理

    2019-09-25 19:30:02
    出于某些原因,需要学习一下spring的安全框架。(研究半天,如果单单说用户认证和授权这块儿,我感觉还是shiro好用。) spring security介绍可以参考一下以下文档: (满满的羡慕啊)我这里就不扯了。 ...
  • 市面上做认证和权限的开发框架还有shiro,spring boot也提供了shiro的解决方案,本人在之前的开发中大多使用了shiro,但是spring security也是值得一的,除了官方推荐的原因像spring oauth2.0也会用到它,所以学习...
  • 相比较Shiro而言,Security功能更加的强大,它可以很容易地扩展以满足更多安全控制方面的需求,但也相对它的学习成本会更高,两种框架各有利弊.实际开发中还是要根据业务和项目的需求来决定使用哪一种.JWT是在Web应用中...
  • <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> ``` shiro-config.xml配置: ``` xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ...
  • 在看完Shiro框架文章时,我们大致应该知道了,了解了安全框架应该去做哪些事情,并且随着微服务架构的发展,Spring Security框架在安全框架的地位也发展的越来越好,所以,了解Spring Security框架的使用还是很有...
  • 相比较Shiro而言,Security功能更加的强大,它可以很容易地扩展以满足更多安全控制方面的需求,但也相对它的学习成本会更高,两种框架各有利弊.实际开发中还是要根据业务和项目的需求来决定使用哪一种.JWT是在Web应用中...
  • 作者|Sans_...相比较Shiro而言,Security功能更加的强大,它可以很容易地扩展以满足更多安全控制方面的需求,但也相对它的学习成本会更高,两种框架各有利弊.实际开发中还是要根据业务...
  • 今天跟大家分享SpringBoot 整合SpringSecurity示例实现...相比较Shiro而言,Security功能更加的强大,它可以很容易地扩展以满足更多安全控制方面的需求,但也相对它的学习成本会更高,两种框架各有利弊.实际开发中还是...
  • 在WEB开发中,安全应该放在第一位,前面我们过一些简单的安全策略,过滤器和拦截器 安全是一个非功能性需求 安全应该在WEB开发的设计的时候就应该考虑在内...比较知名的WEB安全框架有Shiro和SpringSecurity,这两个.
  • 相比较Shiro而言,Security功能更加的强大,它可以很容易地扩展以满足更多安全控制方面的需求,但也相对它的学习成本会更高,两种框架各有利弊.实际开发中还是要根据业务和项目的需求来决定使用哪一种. JWT是在Web应用中...

空空如也

空空如也

1 2 3
收藏数 48
精华内容 19
关键字:

学shiro还是security