2012-11-19 91 views
1

創建一個Bean來驗證我的登錄表單在過去的日子裏,我一直在嘗試使用spring安全性創建一個自定義登錄頁面,但是我沒有找到一個工作示例也沒有自己想出如何使用spring來驗證表單,並相信我,我嘗試了eveything,我可能在google上找到的每個相關示例。如何使用Spring Security 3.1.3和JSF

表單加載正常,everythins正常,我需要的是讓Spring Security在單擊「Login」按鈕時對數據庫驗證憑據。

讓我把它分解成幾部分來解釋。

所以,我有一個登錄表單:

<h:form> 
<p:panelGrid columns="2"> 

    <p:outputLabel for="j_username" value="Usuário:"/> 
    <p:inputText id="j_username" 
       title="Preencha com o seu usuário (login)." 
       required="true" 
       requiredMessage="O campo usuário é obrigatório." 
       value="#{loginBean.usuario}"/> 

    <p:outputLabel for="j_password" value="Senha:"/> 
    <p:password id="j_password" 
       title="Preencha com a sua senha." 
       required="true" 
       requiredMessage="O campo senha é obrigatório." 
       value="#{loginBean.senha}"/> 

     <p:inputText type="hidden"/> 

     <p:panelGrid columns="2" styleClass="customPanelgridTable"> 
     <p:outputLabel for="_spring_security_remember_me" value="Lembrar senha? "/> 
     <p:selectBooleanCheckbox id="_spring_security_remember_me" 
            value="#{loginBean.lembrar_me}"/> 
     </p:panelGrid> 

     <f:facet name="footer"> 
     <p:commandButton value="Entrar" 
         actionListener="#{loginBean.doLogin}"/> 
     </f:facet> 
</p:panelGrid> 
</h:form> 

我需要方法 「doLogin」 驗證使用Spring Security的憑據。

我LoginBean:

@Named 
@SessionScoped 
public class LoginBean implements Serializable { 

private static final long serialVersionUID = 1L; 

private String usuario, senha; 
private boolean lembrar_me = false; 

public String getUsuario() { 
    return usuario; 
} 

public void setUsuario(String usuario) { 
    this.usuario = usuario; 
} 

public String getSenha() { 
    return senha; 
} 

public void setSenha(String senha) { 
    this.senha = senha; 
} 

public boolean isLembrar_me() { 
    return lembrar_me; 
} 

public void setLembrar_me(boolean lembrar_me) { 
    this.lembrar_me = lembrar_me; 
} 

public void doLogin() { 
    //Spring validation... 
} 

} 

我怎麼能這樣做?

的applicationContext.xml

<http security="none" pattern="/javax.faces.resource/**" /> 
<http security="none" pattern="/static/**"/> 
<http auto-config="true" use-expressions="true" 
        access-denied-page="/public/login.xhtml"> 

    <intercept-url pattern="/public/**" access="permitAll"/> 
    <intercept-url pattern="/secure/**" access="hasRole('ROLE_USER')"/> 
    <intercept-url pattern="/login.xhtml" access="permitAll"/> 
    <intercept-url pattern="/**" access="hasRole('ROLE_USER')"/> 
    <form-login login-page="/public/login.xhtml" 
       authentication-failure-url="/public/login.xhtml?erro=true" 
       default-target-url="/secure/secure.xhtml"/> 

</http> 

<beans:bean id="dataSource" 
      class="org.springframework.jdbc.datasource.DriverManagerDataSource" > 

    <beans:property name="url" value="jdbc:mysql://localhost:3306/gde" /> 
    <beans:property name="driverClassName" value="com.mysql.jdbc.Driver" /> 
    <beans:property name="username" value="root" /> 
    <beans:property name="password" value="" /> 
</beans:bean> 

<authentication-manager> 
    <authentication-provider> 

     <user-service> 
      <user name="teste" password="teste" authorities="ROLE_USER"/> 
     </user-service> 

     <jdbc-user-service data-source-ref="dataSource" 
          users-by-username-query="SELECT USUARIO as username, ISATIVO as enabled FROM usuario WHERE USUARIO=?" 

          authorities-by-username-query="SELECT USUARIO as username, AUTORIZACOES as authority FROM usuario_tipo_usuario WHERE USUARIO=?" 
     /> 
    </authentication-provider> 
</authentication-manager> 

任何幫助非常感謝,我堅持這個好幾天!

+0

完全重複的[如何驗證一個登錄內部的bean使用彈簧證券](http://stackoverflow.com/questions/13481299/how-to-validate-a-登錄 - 一個bean-using-spring-security/13497190#13497190)和可能的[spring-custom-jsf-login-page-always-bad-credentials]的重複(http://stackoverflow.com/questions/ 11742283/spring-custom-jsf-login-page-always-bad-credentials/11746589#11746589) – Ravi

回答

0

由於您需要primefaces的漂亮ajax功能,因此無法使用spring security提供的UsernamePasswordAuthenticationFilter。嘗試直接調用AuthenticationManager,然後(The Authentication Manager and the Namespace解釋如何獲取對它的引用)。

+0

您的意思是例如使用表單數據創建一個Authentication對象,並嘗試使用我在applicationContext.xml上設置的身份驗證管理器對其進行身份驗證? 我曾經嘗試過這樣的事情,但我無法獲得經理的參考。 我試着在appcontext.xml中設置alias =「authenticationManager」,然後使用@Property(name =「authenticationManaget」)獲取它,但它返回null,我嘗試並再次嘗試,直到我放棄了。 – victor

+0

是的。注入認證管理器應該與注入任何其他彈簧bean沒有區別。 (可能是Annotation中的輸入錯誤?對其他spring bean使用@Property註釋工作嗎?順便說一句,什麼包定義了這個註釋?) – meriton

+0

是不是可以通過bean重定向來完成?我的意思是這樣的: public void login(){ //發送重定向到「/ portal/j_spring_security_check?j_username =」+ login +「&j_password =」+ passwd「; – victor

0

您不需要bean來驗證spring安全登錄。

要自定義表單登錄,表單登錄元素是正確的地方,您確實可以將一個JSF頁面指定爲login-page。但是,該登錄頁面必須提供春季安全登錄頁面的預期行爲。要理解這種行爲,閱讀其中列出了以下可選參數reference documentation of the form-login element

登錄處理的URL

映射到UsernamePasswordAuthenticationFilter的filterProcessesUrl財產。默認值是「/ j_spring_security_check」。

密碼參數

其包含口令的請求參數的名稱。默認爲「j_password」。

用戶名參數

其中包含的用戶名的請求參數的名稱。默認爲「j_username」。

也就是說,spring security期望憑據作爲http post的請求參數傳遞給特定的url。您的JSF表單違反了該合同:它被張貼到錯誤的URL(因爲您使用h:表單,期望JSF處理表單提交請求)。改爲使用html <form>

至於如何從數據庫加載用戶詳細信息,參考文檔涵蓋了這一點在Using other Authentication Providers

+0

首先,非常感謝你的時間。 看,事情是,我不能使用

。 我需要,因爲如果我使用,(primefaces按鈕)將不起作用。 這就像登錄的Primefaces展示:http://www.primefaces.org/showcase/ui/dialogLogin.jsf 我需要按鈕才能工作,所以我可以訪問doLogin並檢索ajax參數。 在我的bean上需要類似這樣的東西: if(#spring security check ok){ auth = true; } else {auth = false} } 正如您所見,我也可以使用咆哮。 你覺得不值得這麼麻煩嗎? 你覺得不值得麻煩? – victor

+0

你真的應該在你的問題中提到這些限制。將提供另一個答案... – meriton

+0

對不起,我預計會提供一個bean。無論如何,沒有任何理由,你是對的。 我已經在這裏發佈了一個解決方法(http://forum.springsource.org/showthread.php?132463-a-workaround-for-custom-login-bean),其中我試圖創建2個表單(1個隱藏)並使用對話框中的數據填寫隱藏的表單並通過javascript submit()提交,但我發現它非常專業且懶惰。 我真的很累,很想相信我應該離開它並使用表單... – victor