PIXNET Logo登入

Jemmy Walker

跳到主文

部落格全站分類:不設分類

  • 相簿
  • 部落格
  • 留言
  • 名片
  • 4月 06 週二 201017:50
  • Spring-Security3儲存Session方式

  使用SecurityContextHolder來偷窺登入帳號密碼,手段還真是不夠文雅。Spring-Security3是有提供取得登入資訊塞到Session的實踐,不過寫起來很煩,很煩也大概不易被破解^^。Google這方面的資訊,不是缺漏,就是講述古早的版本,還有中文網站,資訊雖新,卻常出現文章一大抄的謬誤,我目前是用3.0.2版,和3.0.1、3.0.0差異何在也不知,不過至少我這方面有踹通,實踐方式和Google內容還是有些關鍵性的差異:   第一個應該是security-context.xml的設定了:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="
http://www.springframework.org/schema/security"
xmlns:beans="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
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
    <http use-expressions="true" auto-config="true">
        <intercept-url pattern="/*.do" access="hasRole('ROLE_USER')"/>
        <intercept-url pattern="/login.jsp" access="isAnonymous()"/>
        <intercept-url pattern="/**" access="permitAll"/>
        <form-login login-processing-url="/j_spring_security_check"
         login-page="/login.jsp" default-target-url="/echo.do"
         authentication-failure-url="/login.jsp?error=1"/>
        <logout logout-url="/j_spring_security_logout" logout-success-url="/login.jsp"/>
        <custom-filter before="FORM_LOGIN_FILTER" ref="authenticationProcessingFilter"/>
        <session-management invalid-session-url="/timeout.html">
            <concurrency-control max-sessions="1" />
        </session-management>
    </http>
    <authentication-manager alias="authenticationManager">
        <authentication-provider user-service-ref="securityManager"/>
    </authentication-manager>
    <beans:bean id="securityManager"
        class="com.foo.dao.impl.UserDetailsServiceImpl"/>
   
<beans:bean id="authenticationProcessingFilter"
        class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
        <beans:property name="authenticationManager" ref="authenticationManager"/>
        <beans:property name="authenticationSuccessHandler">
            <beans:bean class="com.foo.security.MyAuthenticationSuccessHandler">
                <beans:property name="defaultTargetUrl" value="/echo.do"/>
            </beans:bean>
        </beans:property>
        <beans:property name="filterProcessesUrl" value="/j_spring_security_check"/>       
    </beans:bean>
</beans:beans>

  紅字是之前SecurityContextHolder飯粒多出來的設定,真正是靠腰的多。<http>標籤多出<custom-filter>指向authenticationProcessingFilter這個bean,而Google的before後所接的定字幾乎都錯,都是這麼寫: <custom-filter before="AUTHENTICATION_PROCESSING_FILTER" ref="authenticationProcessingFilter"/>   可是Filter的列舉(枚舉)型態裡,根本沒這有AUTHENTICATION_PROCESSING_FILTER這號人物,其它的參考下列表,我原本用CONCURRENT_SESSION_FILTER過不了關,後來改成FORM_LOGIN_FILTER才Pass,Spring-Seucrity 3這部份很像Struts2的Interceptor Stack,從下表來看,應該是有順序,LOGOUT_FILTER排在FORM_LOGIN_FILTER之前…嗯~~也蠻合理的。

Enumerated Values :
    - FIRST
    - CHANNEL_FILTER
    - CONCURRENT_SESSION_FILTER
    - SECURITY_CONTEXT_FILTER
    - LOGOUT_FILTER
    - X509_FILTER
    - PRE_AUTH_FILTER
    - CAS_FILTER
    - FORM_LOGIN_FILTER
    - OPENID_FILTER
    - BASIC_AUTH_FILTER
    - SERVLET_API_SUPPORT_FILTER
    - REMEMBER_ME_FILTER
    - ANONYMOUS_FILTER
    - EXCEPTION_TRANSLATION_FILTER
    - SESSION_MANAGEMENT_FILTER
    - FILTER_SECURITY_INTERCEPTOR
    - SWITCH_USER_FILTER
    - LAST

  <custom-filter>選擇FORM_LOGIN_FILTER時機委給Bean-authenticationProcessingFilter使用,這一動作出現頻道蓋台,<form-login>標籤應該失效,委給authenticationProcessingFilter處理。authenticationProcessingFilter顯然是指定org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter來處理的,此處在Google上又會得到錯誤類別名,正名是UsernamePasswordAuthenticationFilter,而Google的類別名是UsernamePasswordAuthenticationProcessingFilter,多出了Processing,所以我才猜是不是前版的遺留,至少在3.0.2版沒這個類別。   authenticationProcessingFilter要指定三類properties,第一個是指定Authentication Manager。若非這次的需求,SecurityContextHolder會找到<authentication-manager>這個標籤作為預設值。但既然委託給Spring Bean處理,所以要有的bean reference的name,所以後來才在<authentication-manager>加個alias屬性,這樣<authentication-manager>才能被authenticationProcessingFilter找到。   authenticationProcessingFilter要指定的第二類properties是本篇文章目的主程式所在,儲存username至session。最多有四種bean,最常用的是認證成功(AuthenticationSuccessHandler)和認證失敗(AuthenticationFailureHandler),尚有未認證的訪問及已認證訪問受保護的URL。而儲存至session的動作在第一種,是故AuthenticationSuccessHandler屬性指向MyAuthenticationSuccessHandler這個類別,其實作如下:

public class MyAuthenticationSuccessHandler extends
        SavedRequestAwareAuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
            HttpServletResponse response, Authentication authentication)
            throws ServletException, IOException {
        HttpSession session = request.getSession();
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        session.setAttribute("username", userDetails.getUsername());
        super.onAuthenticationSuccess(request, response, authentication);
    }
}

  和前一篇SecurityContextHolder飯粒原理是一樣,只是比較文雅,而MyAuthenticationSuccessHandler下設了一個defaultTargetUrl屬性,其實也恰恰覆蓋<form-login>的default-target-url屬性。先前有言,<customer-filter>若設置為CONCURRENT_SESSION_FILTER過不了關,是session值在onAuthenticationSuccess的設定無法帶給defaultTargetUrl,所以改成FORM_LOGIN_FILTER就可以work。   第三類是filterProcessesUrl屬性,指authenticationProcessingFilter會對哪個URL Pattern產生作用,本例是指/j_spring_security_check,就因為custom-filter設置before="FORM_LOGIN_FILTER"搶在<form-login>攔截,致使<form-login>失效。
(繼續閱讀...)
文章標籤

Jemmy 發表在 痞客邦 留言(0) 人氣(979)

  • 個人分類:Spring-Security
▲top
  • 3月 28 週日 201023:55
  • 取得j_spring_security_check的登入ID及密碼

  再回頭閱讀Spring-Security3的文件,它提供一個獨立於其它Context之外(包括HTTP的Session)的運作環境:SecurityContextHolder,所以透過j_spring_security_check登入的資訊需從此處取得,可以在Action、Custom Tag或一般Java Class取得,如下:

Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
    logger.debug("username=" + ((UserDetails)principal).getUsername());
    logger.debug("pwd=" + ((UserDetails)principal).getPassword());
} else {
    logger.debug("username=" + ((UserDetails)principal).getUsername());
}

  偷窺登入者ID、Password過程有點麻煩,這也可知UserDetails是怎麼來的。
(繼續閱讀...)
文章標籤

Jemmy 發表在 痞客邦 留言(0) 人氣(553)

  • 個人分類:Spring-Security
▲top
  • 3月 23 週二 201018:13
  • Spring-Security3的Session議題

  使用Spring-Security3的session control,要先在web.xml做以下的設定:

<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>
<listener>
    <listener-class>
        org.springframework.security.web.session.HttpSessionEventPublisher
    </listener-class>
</listener>
<session-config>
    <session-timeout>2</session-timeout> <!-- Unit: minutes -->
</session-config>

  很奇怪若把<listener-class>寫到同一個<listen>下會錯。OK,再來是設定Security-context.xml的內容:

<http use-expressions="true" auto-config="true">
    ...
    <session-management invalid-session-url="/timeout.html">
        <concurrency-control max-sessions="1" />
    </session-management>

</http>

  通常只需設定invalid-session-url屬性導向某個頁面就好,若希望同時間對同一個user帳號只允許一個session來連結,可以加入<concurrency-control max-sessions="1"/>的設定。   有件事還解不出,就是invalid-session-url這屬性會蓋掉<logout>標籤的logout-success-url的屬性值,也就是當Logout成功,會被導到invalid-session-url屬性所指的URL。
(繼續閱讀...)
文章標籤

Jemmy 發表在 痞客邦 留言(0) 人氣(447)

  • 個人分類:Spring-Security
▲top
  • 3月 16 週二 201010:25
  • context:include-filter的regex type被Spring-Security屏蔽

  越成功的產品,越有細微的Bug,Spring3也不例外,在整合Spring-Security時(請參考Spring-Security 3初體驗),<context:include-filter>的type不管怎麼指定,都會被Spring-Security使用AspectJ語法屏蔽,下例applicationContext.xml內容紅字部份即是明明指定regex type,卻可以用aspectJ語法,而指定的regex語法不能用。

<context:component-scan base-package="com.foo" use-default-filters="false">
    <context:include-filter type="regex" expression="com.foo.bar..*Config"/>
    <context:include-filter type="regex" expression="com.foo.util.aop.*"/>
</context:component-scan>
<aop:aspectj-autoproxy proxy-target-class="true"/>

  雖然我在web.xml對這兩context.xml做檔名改變,讓applicationContext.xml先載入,再載入Security的context.xml,有成功一次解掉屏蔽,之後第二天還是不行。不知為何?
(繼續閱讀...)
文章標籤

Jemmy 發表在 痞客邦 留言(0) 人氣(78)

  • 個人分類:Spring-Security
▲top
  • 3月 05 週五 201022:30
  • Spring-Security 3初體驗

  使用Spring Security 3來保護頁面。這篇Blog是寫得非常好的Spring-Security 3的入門飯粒。已於2010/2/19發行了3.0.2版了。   Spring-Security已把認證授權該實作的細節隱藏得相當好,開發者可只須注重業務層次。其官方文件強調Spring-Security是以Layer(層)作為Security控管的單位。業務層次的程式是以繼承UserDetails和UserDetailsService兩大介面為主,範例裡講得蠻清楚的。這裡是對Configruation file加以補述。   第一步是設定web.xml。必要設定如下:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
            /WEB-INF/security-config.xml
    </param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

  主要設定有二:一個是設定Filter(紅字部份),可以使Spring-Security在Web起作用,作用範圍就是url-pattern所指定的。第二個是畫有底線的security-config.xml,由Spring Context載入,為Spring Security設定所在。   第二步是Spring config的設定(security-config.xml):

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="
http://www.springframework.org/schema/security"
xmlns:beans="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
 http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
   
<http use-expressions="true" auto-config="true">
        <intercept-url pattern="/secure/protected.jsp" access="hasRole('ROLE_USER')"/>
        <intercept-url pattern="/login.jsp" access="isAnonymous()"/>
        <intercept-url pattern="/**" access="permitAll"/>
        <form-login login-processing-url="/j_spring_security_check"
         login-page="/login.jsp" default-target-url="/index.jsp"
         authentication-failure-url="/login.jsp?error=1"/>
        <logout logout-url="/j_spring_security_logout"/>
    </http>
    <authentication-manager>
        <authentication-provider user-service-ref="securityManager"/>
    </authentication-manager>
    <beans:bean id="securityManager" class="com.blogspot.lawpronotes.security.SecurityManager"/>
</beans:beans>

  <http>標籤目的在於透過AOP方式指定URL Pattern的使用權限,其auto-config="true"的設定,可以在url pattern不用明確指定,比如pattern="/**"即是指其它的URL Pattern皆適用;而use-expression="true"的設定,可以在access屬性使用Spring EL(Spring Expression Language),是故:
  • hasRole('ROLE_USER'):只允許ROLE_USER存取。而像hasAnyRole('Role1', 'Role2', …)則可設定多角色存取。
  • isAnonymous():只允許尚未Login的存取。
  • permitAll:表示url pattern不限制任何角色皆可存取。
  •   而Spring EL尚有以下的common built-in expression:principal、authentication、denyAll、isRememberMe()、isAuthenticated()、isFullyAuthenticated()等,以及Web Security Expression如:hasIpAddress。是故可以如下用and方式P設定: <intercept-url pattern="/admin*" access="hasRole('admin') and hasIpAddress('192.168.1.0/24')"/>   除了Common built-in和Web Security的Expression之外,也提供annotation expression,如Method Security Expression,使用它的話事先要在context.xml宣告如下 <global-method-security pre-post-annotations="enabled"/>   如此一來才能在Bean Class的method做這樣的設定:

    @PreAuthorize("hasRole('ROLE_USER')")
    public void create(Contact contact);
    // OR
    @PreAuthorize("hasPermission(#contact, 'admin')")
    public void deletePermission(Contact contact, Sid recipient, Permission permission);
    // OR
    @PreAuthorize("#contact.name == principal.name)")
    public void doSomething(Contact contact);

      上述的security-context.xml尚未講到<form-login>和<logout>兩個標籤,各自對映到/j_spring_security_check和/j_spring_security_logout,這是Spring Security預設的Filter URL,當然可以改寫,但超出自身修維之外了。   整個流程是:
  • <http>標籤對url pattern過濾後轉給<authentication-manager>指定的bean處理,該bean即繼承UserDetailsService的class。
  • 藉由該bean的loadUserByUsername這個method去存取DB或LDAP驗證,驗證成功再return繼承UserDetails的instance。
  • return後由Spring-Security去驗證密碼和授權,來決定是否允許access。
  • 在上面步驟2和3之間,繼承UserDetails的instance在被New出時,就要設好其interface的屬性,重要如username、password和Authorizes等,這些來源應該在執行loadUserByUsername結束之前就要完成設置。
  • (繼續閱讀...)
    文章標籤

    Jemmy 發表在 痞客邦 留言(0) 人氣(818)

    • 個人分類:Spring-Security
    ▲top
    1

    自訂側欄

    自訂側欄

    個人資訊

    Jemmy
    暱稱:
    Jemmy
    分類:
    不設分類
    好友:
    累積中
    地區:

    熱門文章

    • (2,912)Java在換行字元的issue
    • (1,417)非我族類的DataTables.js:分頁和排序無作用原因
    • (1,319)Oracle的Array型態定義與存取
    • (776)OGG for Java開發
    • (577)Struts-Menu初體驗
    • (542)Perl的跨行比對
    • (436)ORA-08002
    • (76)Notes的DateTime
    • (73)Notes的Agent二三事
    • (32)六句聯

    文章分類

    • PostgreSQL (1)
    • Ruby (6)
    • 圖書 (18)
    • 旅行 (8)
    • OSGi (13)
    • 健康 (9)
    • Google (6)
    • 歷史 (5)
    • Spring-Security (5)
    • Java Script (11)
    • Log (8)
    • 娛樂 (25)
    • IT趨勢 (12)
    • 心情 (92)
    • 組織 (41)
    • Java基本功 (18)
    • Regex (19)
    • 新聞與政治 (46)
    • 電腦和網際網路 (47)
    • Maven (28)
    • Spring (31)
    • LotusNotes (12)
    • Java (60)
    • Oracle (17)
    • Struts (21)
    • jQuery (10)
    • 未分類文章 (1)

    最新文章

    • JDOM解析XML字串(非檔案)
    • Android SDK不能用於JDK 64bit
    • 非我族類的DataTables.js:分頁和排序無作用原因
    • java.lang.IllegalStateException: Committed之解
    • PostgreSQL二三事
    • Form/Field V.S. Document/Item
    • Spring Mail
    • Ant generate manifest.mf的class-path清單
    • dhcp.bat
    • Java update Notes的DateTime欄位

    最新留言

    • [21/07/31] D 於文章「複習一下Servlet的機制...」留言:
      請問更換瀏覽器 Servlet的instance vari...
    • [17/05/04] 訪客 於文章「設定Source編碼...」留言:
      謝謝你~~...
    • [15/08/23] 洪秀柱 於文章「UltraEdit轉大小寫...」留言:
      此破解法可用於 UEstudio UltraEdit V2...
    • [10/10/15] Jemmy 於文章「Perl的跨行比對...」留言:
      哈! 學長, 好久不見了。幸虧這案子沒有Nested Tag...
    • [10/10/14] Benson 於文章「Perl的跨行比對...」留言:
      如果有Nested Tag, 這就不太適用; 我有時還是乖乖...
    • [10/05/25] 世文 於文章「JSON-Lib初體驗...」留言:
      用心經營的blog~^^ 加油!<br />---<br ...
    • [10/05/15] Jemmy 於文章「千分位...」留言:
      你的解法太高深了, 有空再練^^...
    • [10/05/14] Benson 於文章「千分位...」留言:
      可能是 gxe, 不管是 perl or java, 你懂我...
    • [10/05/14] Jemmy 於文章「千分位...」留言:
      練功一下而已, 而且我是要用Java,所以無法用Perl...
    • [10/05/14] Benson 於文章「千分位...」留言:
      學弟,你的問題是什麼呢?是把在引號內數字逗號去掉嗎?s/\"...

    動態訂閱

    文章精選

    文章搜尋

    誰來我家

    參觀人氣

    • 本日人氣:
    • 累積人氣: