• 学习笔记--shiro


    shiro配合spring

    1.配置SecurityManager

        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <property name="cacheManager" ref="cacheManager"/>
            <!-- Single realm app.  If you have multiple realms, use the 'realms' property instead. -->
            <property name="sessionMode" value="native"/>
            <property name="realm" ref="jdbcRealm"/>
        </bean>
    

    2.配置CacheManager
    2.1 需要加入ehcache的jar包和配置文件

        <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
            <!-- Set a net.sf.ehcache.CacheManager instance here if you already have one.  If not, a new one
                will be creaed with a default config:
                <property name="cacheManager" ref="ehCacheManager"/> -->
            <!-- If you don't have a pre-built net.sf.ehcache.CacheManager instance to inject, but you want
                a specific Ehcache configuration to be used, specify that here.  If you don't, a default
                will be used.:
            <property name="cacheManagerConfigFile" value="classpath:some/path/to/ehcache.xml"/> -->
            <property name="cacheManagerConfigFile" value="classpath:ehcache.xml" />
        </bean>
    

    3.配置Realm
    3.1 直接配置实现了org.apache.shiro.realm.Realm接口的bean

        <bean id="jdbcRealm" class="com.kioluo.shiro.realms.ShiroRealm">
        </bean>
    

    4.配置LifecycleBeanPostProcessor,可以自定的来调用配置在spring IOC容器中的shiro bean生命周期方法

        <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    

    5.启用IOC容器中的shiro注解,但必须在配置了LifecycleBeanPostProcessor之后才可以使用

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

    6.配置ShiroFilter
    6.1 id必须和web.xml中的DelegatingFilterProxy的一致,若不一致则会抛出NoSuchBeanDefinitionException。DelegatingFilterProxy实际上是Filter的一个代理对象,默认情况下Shiro会来IOC容器查找和对应名字的filter bean,也可以通过targetBeanName的初始化参数来配置filter bean的id。

    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager"/>
            <property name="loginUrl" value="/login.jsp"/>
            <property name="successUrl" value="/user.jsp"/>
            <property name="unauthorizedUrl" value="/unauthorized.jsp"/>
            <!-- The 'filters' property is not necessary since any declared javax.servlet.Filter bean
                defined will be automatically acquired and available via its beanName in chain
                definitions, but you can perform overrides or parent/child consolidated configuration
                here if you like: -->
            <!-- <property name="filters">
                <util:map>
                    <entry key="aName" value-ref="someFilterPojo"/>
                </util:map>
            </property> -->
            <property name="filterChainDefinitions">
                <value>
                    /login = anon
                    # everything else requires authentication:
                    /** = authc
                </value>
            </property>
        </bean>
    

    6.2 URL匹配模式

    • ?(一个字符)
    • *(零或多个字符)
    • **(零或多个路径)
      原则:第一次匹配优先

    认证思路

    1. 获取当前的Subject,调用SecurityUtils.getSubject();
    2. 测试当前的用户是否已经被认证,即是否已经登录,调用Subject的isAuthenticated()
    3. 若没有被认证,则把用户名和密码封装为UsernamePasswordToken对象
    4. 执行登录:调用Subject的login(AuthenticationToken)方法
    5. 自定义Realm方法,从数据库中获取对应的记录,返回给Shiro
      5.1 实际上需要继承org.apache.shiro.realm.AuthenticatingRealm类
      5.2 实现doGetAuthenticationInfo(AuthenticationToken)方法
    6. 由shiro完成密码的比对(通过AuthenticatingRealm的credentialsMatcher属性来进行密码的比对)
      6.1 MD5加密,配置credentialsMatcher为HashedCredentialsMatcher,hashAlgorithmName为MD5
      6.2 MD5盐值加密
            ByteSource credentialsSalt = ByteSource.Util.bytes(username);
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realm);
            Object result = new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations);
    

    7.多Realm认证,配置org.apache.shiro.authc.pam.ModularRealmAuthenticator(默认是AtLeastOneSuccessfulStrategy)
    8.AuthenticationStrategy接口(三种实现FirstSuccessfulStrategy, AtLeastOneSuccessfulStragegy, AllSuccessfulStrategy)

    授权方式

    • 编程式
    • 注解式
    • JSP/GSP标签

    身份验证
    拦截器名:authc、authcBasic、logout、user、anon

    授权实现
    授权需要继承AuthorizingRealm类,并实现其doGetAuthorizationInfo方法
    AuthorizingRealm类继承自AuthenticatingRealm,但没有实现AuthenticatingRealm中的doGetAuthenticationInfo,所以认证和授权只需要继承AuthorizingRealm就可以了,同时实现他的两个抽象方法
    实现doGetAuthorizationInfo方法:

    • 从PrincipalCollection中来获取登录用户的信息
    • 利用登陆的用户的信息来获取当前用户的角色或权限(可能需要查询数据库)
    • 创建SimpleAuthorizationInfo,并设置其roles属性
    • 返回SimpleAuthorizationInfo对象

    Shiro标签

    JSTL标签

    <shiro:guest>...</shiro:guest>
    <shiro:user>...</shiro:user>
    <shiro:principal property="username" />
    <shiro:hasRole name="admin">...</shiro:hasRole>
    

    权限注解

    @RequiresAuhtentication
    @RequiresUser
    @RequiresGuest
    @RequiresRoles(value={"admin", "user"}, logical=Logical.AND)
    @RequiresPermissions(value={"user:a", "user:b"}, logical=Logical.OR)
    

    从数据表初始化资源和授权

    配置一个bean,该bean实际上是一个Map。通过实例工厂方法的方式获取

        <bean id="factory" factory-bean="filterChainDefinitionFactory" factory-method="buildFilterChainDefinition"/>
        <bean id="filterChainDefinitionFactory"
              class="com.kioluo.shiro.factorys.FilterChainDefinitionFactory"/>
    

    设置ShiroFilterFactoryBean的property

            <property name="filterChainDefinitionMap" ref="factory" />
    

    会话管理

    controller层的HttpSession可以在service层通过shiro的会话管理得到

    SecurityUtils.getSubject().getSession();
    

    SessionDAO接口及其实现类
    AbstractSessionDAO、CachingSessionDAO、MemorySessionDAO、EnterpriseCacheSessionDAO

    session配置

    • Session ID生成器
    • SessionDAO实现,继承EnterpriseCacheSessionDAO
    • 会话管理器

    会话验证
    会话验证调度器SessionValidationScheduler、QuartzSessionValidationScheduler

  • 相关阅读:
    C#多线程参数传递
    Delphi单元测试工具Dunit介绍
    使用javascript生成文件
    Windows自动登录源码
    [Win32]一个调试器的实现
    用MASM写一个简单的实现递归操作的汇编程序,所谓递归,上课已经跟大家说清楚了,如果我们只考虑简单的只分一次的递
    C#多线程编程(4)多线程与UI操作
    在Delphi中实现类型安全的容器,Delphi泛型库DGL引介(提供源码下载) .
    delphi 中几种多线程操作方式
    C#实现WEB服务器
  • 原文地址:https://www.cnblogs.com/kioluo/p/8824745.html
Copyright © 2020-2023  润新知