2011-12-30 55 views
18

我們使用spring security 3.0.5,Java 1.6和Tomcat 6.0.32。在我們的.xml配置文件中,我們已經有了:如何使用spring security從失敗登錄中獲取用戶名?

<form-login login-page="/index.html" default-target-url="/postSignin.html" always-use-default-target="true" 
authentication-failure-handler-ref="authenticationFailureHandler"/> 

和我們authenticationFailureHandler定義爲:

<beans:bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler"> 
    <beans:property name="exceptionMappings"> 
     <beans:props> 
    <beans:prop key="org.springframework.security.authentication.BadCredentialsException">/index.html?authenticationFailure=true</beans:prop> 
    </beans:props> 
    </beans:property> 
</beans:bean> 

的Java

@RequestMapping(params={"authenticationFailure=true"}, value ="/index.html") 
    public String handleInvalidLogin(HttpServletRequest request) { 
     //... How can I get the username that was used??? 
     // I've tried: 
     Object username = request.getAttribute("SPRING_SECURITY_LAST_USERNAME_KEY"); 
     Object username = request.getAttribute("SPRING_SECURITY_LAST_USERNAME"); // deprecated 
    } 

所以,我們指導所有BadCredentialsExceptionsindex.htmlIndexController。在IndexController中,我想獲取用於登錄嘗試失敗的username。我怎樣才能做到這一點?

回答

20

好的,所以答案結果是非常簡單的,但據我所知,沒有深入討論或記錄。

這裏的一切我不得不這樣做(沒有任何地方剛剛創建此類配置)...

import org.apache.log4j.Logger; 
import org.springframework.context.ApplicationListener; 
import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent; 
import org.springframework.stereotype.Component; 

@Component 
public class MyApplicationListener implements ApplicationListener<AuthenticationFailureBadCredentialsEvent> { 
    private static final Logger LOG = Logger.getLogger(MyApplicationListener.class); 

    @Override 
    public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent event) { 
     Object userName = event.getAuthentication().getPrincipal(); 
     Object credentials = event.getAuthentication().getCredentials(); 
     LOG.debug("Failed login using USERNAME [" + userName + "]"); 
     LOG.debug("Failed login using PASSWORD [" + credentials + "]"); 
    } 
} 

我遠離彈簧安全專家,所以如果有人讀取該和的原因,我們不該知道不要這樣做,或者知道更好的方式,我很樂意聽到它。

+0

我試過了,但它不起作用 – 2012-06-06 08:33:44

+0

我們有這個確切的代碼在我們的設置中工作。我無法告訴你爲什麼它不適合你。我們不必配置任何新的東西,也不需要在任何地方更改任何.xml文件。註釋似乎指向這個代碼的春天,並在出現不良登錄時執行它。它對我們來說非常合適。 – kasdega 2012-06-06 13:35:57

+0

也許它需要一些其他配置。順便說一下,我找到了另一種解決方案。感謝您的信息,雖然:) – 2012-06-07 02:22:40

5

您可以改爲提供您自己的版本DefaultAuthenticationEventPublisher並覆蓋publishAuthenticationFailure方法。

+0

你有這樣一個例子,你可以指向我嗎? – kasdega 2011-12-30 14:36:43

+1

您需要連線您的所有者實施。看看你是否可以擴展DefaultAuthenticationEventPublisher。然後將它連接到ProviderManager(這是您需要在Spring Security中聲明的AuthenticationManager的實現)。該類有一個方法setAuthenticationEventPublisher。 – Saish 2011-12-30 15:32:00

1

我發現這個作品適合我。不幸的是,我還沒有發現這個確切位置在SpringSecurity文件:

在採取任何行動,你可以檢查上次使用的用戶名(不管是什麼登錄是失敗與否):

String username = (String) request.getSession().getAttribute("SPRING_SECURITY_LAST_USERNAME"); 
+1

UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY是對應於屬性名稱的常量。現在已被棄用。 – mrbaboo 2013-01-02 02:11:21

+0

@mrbaboo:所以這就是爲什麼我找不到這個常量的原因。所以它已被棄用,你知道任何替代方式來實現相同的效果? – 2013-01-02 08:11:08

+2

只是想指出,在會話中存儲此棄用值的代碼已在Spring Security的3.1.0版本中刪除。如果您想用最新版本實現此效果,則必須使用上述其他方法之一。 – Jules 2014-03-12 14:12:53

10

我就是這麼做的:

  1. 創建一個擴展SimpleUrlAuthenticationFailureHandler

  2. Overrid的onAuthenticationFailure方法的類,WH ich收到HttpServletRequest作爲參數。

  3. request.getParameter("username"),其中"username"是我在我的HTML表單中輸入的名稱。

+1

它工作正常,只是一個評論,如果您使用的輸入文本是** j_username **的形式的默認名稱,那麼你必須像這樣抓住它。 '的request.getParameter( 「爲j_username」)'。 – OJVM 2017-03-02 14:46:50

1

似乎有不被這個解決方案多的信息,但如果你在你的春季安全配置設置failureForwardUrl,你將被轉發到錯誤頁面,而不是重定向。然後,您可以輕鬆檢索用戶名和密碼。 例如,在你的配置增加: .and().formLogin().failureForwardUrl("/login/failed")(* url必須從登錄頁面URL不同)

而在你的登錄控制器,如下:

@RequestMapping(value = "/login/failed") 
public String loginfailed(@ModelAttribute(UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_USERNAME_KEY) String user, @ModelAttribute(UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_PASSWORD_KEY) String password) { 
    // Your code here 
} 

SPRING_SECURITY_FORM_USERNAME_KEY,SPRING_SECURITY_FORM_PASSWORD_KEY爲默認名稱,但你也可以在FormLoginConfigurer中設置它們:

.and().formLogin().usernameParameter("email").passwordParameter("password").failureForwardUrl("/login/failed") 
相關問題