zoukankan      html  css  js  c++  java
  • 学习笔记--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

  • 相关阅读:
    css实现导航栏切换动画
    ubuntu系统下mysql重置密码和修改密码操作
    Ubuntu16.04 安装配置nginx,实现多项目管理、负载均衡
    每天一点点之数据结构与算法
    vuex基本使用
    在 npm 中如何用好 registry
    django模板
    skywalking 通过python探针监控Python 微服务应用性能
    Centos7新加磁盘扩容根分区
    python3中用HTMLTestRunner.py报ImportError: No module named 'StringIO'如何解决
  • 原文地址:https://www.cnblogs.com/kioluo/p/8824745.html
Copyright © 2011-2022 走看看