Spring集成Apache Shiro安全框架

前段時間項目中用到Apache Shiro安全框架用于實現用戶認證與授權。
參考資料:
http://www.ibm.com/developerworks/cn/web/wa-apacheshiro/
http://www.ibm.com/developerworks/cn/opensource/os-cn-shiro/
http://www.infoq.com/cn/articles/apache-shiro


配置信息

web.xml中通過spring的代理過濾器將過濾交給shiro。同時applicationContext.xml中需要一個叫shiroFilter的過濾器。
代碼如下:

    <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用于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"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd"
    default-lazy-init="true">

    <description>Shiro安全配置</description>

    <!-- Shiro's main business-tier object for web-enabled applications -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="shiroDbRealm" />
    </bean>

    <!-- 項目自定義的Realm, 所有accountService依賴的dao都需要用depends-on聲明 -->
    <bean id="shiroDbRealm" class="xxx.xxx.xxx.service.account.ShiroDbRealm" depends-on="">
        <property name="accountService" ref="accountService"/>
    </bean>
    
    <!-- 自定義url過濾器 -->
    <bean id="URLFilter" class="xxx.xxx.xxx.web.filter.URLFilter">
        <constructor-arg>
        <value>sitemesh=false</value>
        </constructor-arg>
    </bean>
    
    <bean id="UserFormAuthenticationFilter" class="xxx.xxx.xxx.web.filter.UserFormAuthenticationFilter">

    </bean> 
    
    <!-- Shiro Filter /login = authc-->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean" depends-on="UserFormAuthenticationFilter">
         <property name="filters">
            <util:map>
                <entry key="UserFormAuthenticationFilter" value-ref="UserFormAuthenticationFilter"/>
                <entry key="urlFilter" value-ref="URLFilter"/>
            </util:map>
        </property> 
        <property name="securityManager" ref="securityManager" />
        <property name="loginUrl" value="/login" />
        <property name="successUrl" value="/" />
        <property name="unauthorizedUrl" value="/PermissionController/403"/>
        <property name="filterChainDefinitions">
            <value>
                /login = UserFormAuthenticationFilter
                /logout = logout
                /static/** = anon
                /register/** = anon
                /views/**/*.jsp = user,urlFilter
                /** = user
            </value>
        </property>
    </bean>
    
    <!-- 保證實現了Shiro內部lifecycle函數的bean執行 -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    
</beans>

代碼實現部分

ShiroDbRealm繼承AuthorizingRealm類實現用戶認證和授權的方法。

public class ShiroDbRealm extends AuthorizingRealm
{
    private AccountService accountService;

    public ShiroDbRealm() {
        super();
        //setCredentialsMatcher(new AllowAllCredentialsMatcher());
        //設置認證token的實現類,該處使用UsernamepasswordTken,也可自定義token,如果自定義token則需繼承AuthenticationToken;
            setAuthenticationTokenClass(EhrUserToken.class);       
   }
    
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken authcToken) throws AuthenticationException
    {
        return info;
    }
    
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals)
    {
        
        return info;
    }
}

自定義的過濾器繼承AuthenticationFilter

public class URLFilter extends AuthenticationFilter
{

    @Override
    protected boolean onAccessDenied(ServletRequest request,
            ServletResponse response) throws Exception
    {
        HttpServletResponse rsp = (HttpServletResponse)response;
        rsp.sendError(403);
        return false;
    }

    @Override
    public void doFilterInternal(ServletRequest request,
            ServletResponse response, FilterChain chain)
            throws ServletException, IOException
    {
        Exception exception = null;
        try
        {
            //授權成功
            executeChain(request, response, chain);
            postHandle(request, response);
            
            //授權失敗
            onAccessDenied(request,response);   
        } catch (Exception e)
        {
             exception = e;
        }
        finally {
            cleanup(request, response, exception);
        }
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容