2012-08-29 183 views
0

我是一名新的彈簧安全人員,似乎我有一個對我來說太困難的問題,對於常見問題解答和其他站點。PRE_AUTH_FILTER +登錄表單身份驗證

任務是:

  1. 我有一個登錄表單春天應用程序。一切正常。

  2. 現在我需要能夠從應用程序獲得任何允許的頁面,但通過URL驗證...類似於:http://myapp.de?login=test&password=test。我用PRE_AUTH_FILTER做了它。一切都適用於URL。

  3. 問題是我需要兩個身份驗證方式在我的應用程序。假設PRE_AUTH_FILTER失敗,那麼加載標準登錄表單。因此:http://myapp.de將顯示我的登錄表單和第1)點。

現在用我的安全配置,我只有PRE_AUTH_FILTER工作。

我錯過了什麼?

<sec:http auto-config="true" use-expressions="true"> 
    <sec:form-login login-page="/login.jsp" default-target-url="/start" authentication-failure-url="/login.jsp?error=true"/> 
    <sec:logout logout-url="/logout" logout-success-url="/login.jsp"/> 
    <sec:anonymous username="guest" granted-authority="ROLE_ANONYMOUS"/> 
    <sec:access-denied-handler error-page="/error403.jsp"/> 
    <sec:intercept-url pattern="/login*" access="permitAll"/> 
    <sec:intercept-url pattern="/objautocomplete*" access="hasRole('ROLE_USER')"/> 
    <sec:intercept-url pattern="/start*" access="hasRole('ROLE_USER')"/> 
    <sec:intercept-url pattern="/u*" access="hasRole('ROLE_USER')"/> 
    <sec:intercept-url pattern="/crosstable*" access="hasRole('ROLE_USER')"/> 
    <sec:intercept-url pattern="/objcen*" access="hasRole('ROLE_USER')"/> 
    <sec:intercept-url pattern="/objchecks*" access="hasRole('ROLE_USER')"/> 
    <sec:intercept-url pattern="/globalcen*" access="hasRole('ROLE_USER')"/> 
    <sec:custom-filter position="PRE_AUTH_FILTER" ref="preAuthFilter" /> 
    <sec:remember-me/> 
</sec:http> 

    <!-- PRE_ AUTHENTICATION -->   
<beans:bean id="userDetailsServiceImpl" 
    class="com.grsnet.qvs.auth.UserDetailsServiceImpl" /> 

<beans:bean id="preAuthenticatedProcessingFilterEntryPoint" 
    class="com.grsnet.qvs.auth.LinkForbiddenEntryPoint" /> 

<beans:bean id="preAuthenticationProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider"> 
    <beans:property name="preAuthenticatedUserDetailsService" ref="userDetailsServiceImpl" /> 
</beans:bean> 

<beans:bean id="preAuthFilter" 
    class="com.grsnet.qvs.auth.UrlParametersAuthenticationFilter"> 
    <beans:property name="authenticationManager" ref="appControlAuthenticationManager" /> 
</beans:bean> 

<sec:authentication-manager alias="appControlAuthenticationManager"> 
    <sec:authentication-provider ref="preAuthenticationProvider" /> 
</sec:authentication-manager> 

    <!-- LOGIN FORM AUTHENTICATION --> 

<sec:authentication-manager> 
    <sec:authentication-provider user-service-ref="qvsUserDetailsService"/> 
</sec:authentication-manager> 

<beans:bean id="qvsUserDetailsService" class="com.grsnet.qvs.auth.QVSUserDetailsService"/> 

</beans:beans> 

UPDATE UrlParametersAuthenticationFilter.java

public class UrlParametersAuthenticationFilter extends AbstractPreAuthenticatedProcessingFilter { 

    @Override 
    protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) { 
     if (request.getParameterMap().size() == 2) { 
      return true; 
     } 
     return false; 
    } 

    @Override 
    protected Object getPreAuthenticatedCredentials(HttpServletRequest request) { 
     String[] credentials = new String[2]; 
     credentials[0] = request.getParameter("j_username"); 
     credentials[1] = request.getParameter("j_password"); 
     return credentials; 
    } 
} 

回答

1
<sec:custom-filter before="FORM_LOGIN_FILTER" ref="preAuthFilter" /> 

編輯:

呀,所述過濾器是一片混亂。你甚至可以看看AbstractPreAuthenticatedProcessingFilter的javadoc或源代碼嗎? PreAuthentication在外部系統已經完成認證時使用。例如,如果您使用容器提供的Java EE身份驗證,或者您有一個可以進行身份​​驗證的Web前端,例如面向NTLM/Kerberos的IIS。

此外,您已經實現它不正確,getPreAuthenticatedPrincipal()應該返回用戶名稱,即Principal,並且getPreAuthenticatedCredentials應該返回密碼,也稱爲Credentials。但更重要的是,AbstractPreAuthenticatedProcessingFilter 不會執行任何身份驗證。 Javadoc中的第一行:

Base class for processing filters that handle pre-authenticated authentication requests, where it is assumed that the principal has already been authenticated by an external system. 

所以,取消你的過濾器,並使用標準UsernamePasswordAuthenticationFilter

<beans:bean id="urlParameterAuthFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> 
    <beans:property name="usernameParameter" value="username" /> 
    <beans:property name="passwordParameter" value="password" /> 
    <beans:property name="postOnly" value="false" /> 
    <beans:property name="authenticationManager" ref="appControlAuthenticationManager" /> 
</beans:bean> 

然後用

<sec:custom-filter before="FORM_LOGIN_FILTER" ref="urlParameterAuthFilter" /> 

免責聲明替換您的自定義過濾器聲明:傳遞密碼在URL中是一個非常糟糕的主意,你不應該在第一時間做到這一點。它將顯示在訪問日誌中,並引入了一大堆非常不必要的安全問題。

+0

我應該用你的字符串替換我的代碼嗎?或者添加它?當我更換時,我有下一種情況:1.登錄表單工作2. url auth不起作用,並在登錄表單上重定向我。 – mad

+0

更新:有下一個異常:沒有爲org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken發現AuthenticationProvider – mad

+0

更新:當我嘗試調試時,我在userDetailsS​​erviceImpl中沒有任何活動。當我有PRE_AUTH_FILTER時,我有調試活動,它已經工作。 – mad