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

    <description>== Shiro Components ==</description>

    <!-- 会话Session ID生成器 -->
    <bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/>

    <!-- 会话Cookie模板 -->
    <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <constructor-arg value="pqs9900"/>
        <property name="httpOnly" value="true"/>
        <!--cookie的有效时间 -->
        <property name="maxAge" value="-1"/>
        <property name="name" value="9900Cookie" />
    </bean>

    <!-- user shiro session listener -->
    <bean id="userSessionListener" class="com.njcn.shiro.listener.UserSessionListener">
        <property name="userShiroSessionRepository" ref="jedisShiroSessionRepository"/>
    </bean>

    <!-- user shiro session dao -->
    <bean id="userShiroSessionDAO" class="com.njcn.shiro.session.UserShiroSessionDao">
        <property name="userShiroSessionRepository" ref="jedisShiroSessionRepository"/>
        <property name="sessionIdGenerator" ref="sessionIdGenerator"/>
    </bean>

    <!-- 手动操作Session，管理Session -->
    <bean id="userSessionManager" class="com.njcn.shiro.session.UserSessionManager">
        <property name="userShiroSessionRepository" ref="jedisShiroSessionRepository"/>
    </bean>

    <!-- Session Manager -->
    <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <!-- 相隔多久检查一次session的有效性   -->
        <property name="sessionValidationInterval" value="1800000"/>
        <!-- session 有效时间为半小时 （毫秒单位）-->
        <property name="globalSessionTimeout" value="1800000"/>
        <property name="sessionDAO" ref="userShiroSessionDAO"/>
        <!-- session 监听，可以多个。 -->
        <property name="sessionListeners">
            <list>
                <ref bean="userSessionListener"/>
            </list>
        </property>
        <!-- 间隔多少时间检查，不配置是60分钟 -->
        <property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>
        <!-- 会话Cookie模板 -->
        <property name="sessionIdCookie" ref="sessionIdCookie"/>
    </bean>

    <!-- 会话验证调度器 -->
    <bean id="sessionValidationScheduler"
          class="org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler">
        <property name="sessionManager" ref="sessionManager"/>
    </bean>

    <!-- 安全管理器 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="dataRealm"/>
        <property name="sessionManager" ref="sessionManager"/>
        <property name="cacheManager" ref="userShiroCacheManager"/>
    </bean>

    <!-- 用户缓存 -->
    <bean id="userShiroCacheManager" class="com.njcn.shiro.cache.impl.UserShiroCacheManager">
        <property name="shiroCacheManager" ref="jedisShiroCacheManager"/>
    </bean>


    <bean id="jedisManager" class="com.njcn.utils.redis.JedisManager"/>

    <!-- shiro 缓存实现，对ShiroCacheManager，我是采用redis的实现 -->
    <bean id="jedisShiroCacheManager" class="com.njcn.shiro.cache.impl.JedisShiroCacheManager">
        <property name="jedisManager" ref="jedisManager"/>
    </bean>

    <!-- session 创建、删除、查询 -->
    <bean id="jedisShiroSessionRepository" class="com.njcn.shiro.session.impl.JedisShiroSessionRepository">
        <property name="jedisManager" ref="jedisManager"/>
    </bean>


    <!-- 静态注入，相当于调用SecurityUtils.setSecurityManager(securityManager) -->
    <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/>
        <property name="arguments" ref="securityManager"/>
    </bean>

    <!-- 静态注入 jedisShiroSessionRepository-->
    <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="staticMethod" value="com.njcn.shiro.filter.KickoutSessionFilter.setUserShiroSessionRepository"/>
        <property name="arguments" ref="jedisShiroSessionRepository"/>
    </bean>

    <!-- 静态注入 jedisShiroSessionRepository-->
    <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="staticMethod" value="com.njcn.shiro.filter.LoginFilter.setUserShiroSessionRepository"/>
        <property name="arguments" ref="jedisShiroSessionRepository"/>
    </bean>

    <bean id="dataRealm" class="com.njcn.shiro.realm.DataRealm"/>

    <!--
        自定义角色过滤器 支持多个角色可以访问同一个资源 eg:/home.jsp = authc,roleOR[admin,user]
        用户有admin或者user角色 就可以访问
    -->

    <!-- 认证数据库存储-->
    <bean id="login" class="com.njcn.shiro.filter.LoginFilter"/>
    <bean id="role" class="com.njcn.shiro.filter.RoleFilter"/>
    <bean id="permission" class="com.njcn.shiro.filter.PermissionFilter"/>
    <bean id="simple" class="com.njcn.shiro.filter.SimpleAuthFilter"/>

    <!-- session 校验单个用户是否多次登录 -->
    <bean id="kickoutSessionFilter" class="com.njcn.shiro.filter.KickoutSessionFilter"/>

    <!-- shiro filter配置 -->
    <bean id="shiroSecurityFilter" class="com.njcn.shiro.response.NjcnShiroFilterFactoryBean">
        <!-- shiro 的核心安全接口 -->
        <property name="securityManager" ref="securityManager"/>
        <!-- 要求登录时的链接 -->
        <property name="loginUrl" value="/"/>
        <!-- 登陆成功后要跳转的连接 -->
        <property name="successUrl" value="/main"/>
        <!-- 未授权时要跳转的连接 -->
        <property name="unauthorizedUrl" value="/views/auth/unauthorized"/>
        <!-- shiro 连接约束配置 -->
        <!-- url级别权限权限控制 -->
        <property name="filterChainDefinitions">
            <value>
                <!--不需要权限所有用户能直接获取的资源-->
                /css/**=anon
                /js/**=anon
                /images/**=anon
                /json/**=anon
                /jspJS/**=anon
                /jspCSS/**=anon
                /tiles/**=anon
                /theme/**=anon
                /=anon
                /user/generateRSAKey=anon
                /user/ssoRegister=anon
                /druid/**=anon
                /druid=anon
                /auth/**=anon
                /device/websocketon=anon
                /device/socketoReset=anon
                /alarm/alarmTip=anon
                /alarm/unAlarmInfo=anon
                /alarm/alarmForSeverity=anon
                <!--用户相关-->
                /business/user=login,kickout,role[system]
                /user/selectId=login,kickout,role[system,root]
                /user/selectAppId=login,kickout,role[system,root]
                /user/deleteUserByIndex=login,kickout,role[system,root]
                /user/activeUser=login,kickout,role[system,root]
                /user/unlockUser=login,kickout,role[system,root]
                /user/selectAllUser=login,kickout,role[system,root]
                /user/updateExaminer=login,kickout,role[check]
                /user/getAllUserList=login,kickout,role[check]
                /user/getOnlineUsers=login,kickout,role[audit]
                /user/updateAppUser=login,kickout,role[system,root]
                /user/getAreasInfo=login,kickout,role[business]
                /user/loginout=login,kickout,role[system,business,audit,check,root]
                /user/confirmPwd=login,kickout,role[system,business,audit,check,root]
                /user/confirmIndentity=login,kickout,role[system,business,audit,check,root]
                /user/confirmUserPwdIndentity=login,kickout,role[system,business,audit,check,root]
                /user/generateSM2Key=login,kickout,role[system,business,audit,check,root]
                /user/**=login,kickout,role[system]
                <!--角色相关-->
                /business/role=login,kickout,role[system]
                /role/selectAllName=login,kickout,role[check]<!--废弃-->
                /role/**=login,kickout,role[system]
                <!--资源相关-->
                /permission/**=login,kickout,role[system]
                <!--日志相关-->
                /log/getWarnInfo=login,kickout,role[system]
                /log/getWarnInfoCounts=login,kickout,role[system]
                /log/**=login,kickout,role[audit]
                <!--登录记录-->
                /login/**=login,kickout,role[audit]

                <!--部门供电公司操作-->
                /deptsGd/**=login,kickout,role[business]<!--废弃-->
                <!--超级管理员的操作-->
                /managers/**=login,kickout,role[root]
                /manageSystem/**=login,kickout,role[root]
                <!--页面跳转控制-->
                <!--超级管理员页面-->
                /business/managers=login,kickout,role[root]
                /business/managesystem=login,kickout,role[root]
                <!--审核管理员页面-->
                /business/examiner=login,kickout,role[check]
                <!--审计管理员页面-->
                /business/sj=login,kickout,role[audit]
                /business/online=login,kickout,role[audit]
                /business/seriouswin=login,kickout,role[audit]
                /business/sjtj=login,kickout,role[audit]
                /business/chart=login,kickout,role[audit]
                /business/loginmanage=login,kickout,role[audit]
                <!--系统管理员页面-->
                /business/sys=login,kickout,role[system]
                /business/warnwin=login,kickout,role[system]
                /business/rolelist=login,kickout,role[system]
                /business/addUser=login,kickout,role[system]
                /business/addAppUser=login,kickout,role[system]
                /business/updateAppUser=login,kickout,role[system]
                /business/addSys=login,kickout,role[system]
                /business/updateSys=login,kickout,role[system]
                /business/updateUser=login,kickout,role[system]
                /business/updatePassWord=login,kickout,role[system]
                /business/updateAppPassWord=login,kickout,role[system]
                /business/addrole=login,kickout,role[system]
                /business/roledistribute=login,kickout,role[system]
                /business/menu=login,kickout,role[system]
                /business/timermanage=login,kickout,role[system]
                /business/addChildMenu=login,kickout,role[system]
                /business/menuConfig=login,kickout,role[system]
                /business/addConfig=login,kickout,role[system]
                /business/editMenu=login,kickout,role[system]
                /business/destributerole=login,kickout,role[system]
                /business/destributepermission=login,kickout,role[system]
                /business/appUser=login,kickout,role[system]
                /business/message=login,kickout,role[system]
                /business/messageconf=login,kickout,role[system]
                <!--短信页面跳转-->
                /business/virtualsend=login,kickout,role[system]
                /business/msgtime=login,kickout,role[system]
                /business/msgtype=login,kickout,role[system]
                /business/dictype=login,kickout,role[system]
                /business/depets=login,kickout,role[system]
                <!--字典相关操作-->
                /dic/**=login,kickout,role[system,audit,root,check,business]
                <!--字典类型操作-->
                /type/**=login,kickout,role[system,audit,root,check,business]
                <!--部门操作-->
                /depts/**=login,kickout,role[system,audit,root,check,business]
                <!--web工具跳转页面-->
                /csv/**=login,kickout,role[system]
                /deviceTree/**=login,kickout,role[system]
                /business/xbcsv=login,kickout,role[system]
                /business/xbcsvmain=login,kickout,role[system]
                /business/datacomplet=login,kickout,role[system]
                /business/datacompletmain=login,kickout,role[system]
                <!--各管理员共享页面-->
                /business/doBusiness=login,kickout,role[system,audit,root,check,business]
                /business/voltageMain=login,kickout,role[system,audit,root,check,business]
                /business/powerMain=login,kickout,role[system,audit,root,check,business]
                <!--业务管理员页面-->
                /business/**=login,kickout,role[business,system]
                <!--用户配置-->
                /userset/**=login,kickout,role[system]
                <!--系统配置-->
                /sysset/**=login,kickout,role[system]
                <!--短信配置-->
                /message/**=login,kickout,role[system]
                <!--日志备份-->
                /fileBackUp/**=login,kickout,role[audit]
                <!--剩余均是业务管理员的操作，采用通配-->
                /**=login,kickout,role[business,system]


            </value>
        </property>
        <property name="filters">
            <util:map>
                <entry key="login" value-ref="login"/>
                <entry key="role" value-ref="role"/>
                <entry key="simple" value-ref="simple"/>
                <entry key="permission" value-ref="permission"/>
                <entry key="kickout" value-ref="kickoutSessionFilter"/>
            </util:map>
        </property>
    </bean>

    <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

    <bean
            class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
            depends-on="lifecycleBeanPostProcessor">
        <property name="proxyTargetClass" value="true"/>
    </bean>

    <bean
            class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"/>
    </bean>
</beans>

