如何使用 Spring Security 3.1.3 和 JSF 创建一个 Bean 来验证我的登录表单

Posted

技术标签:

【中文标题】如何使用 Spring Security 3.1.3 和 JSF 创建一个 Bean 来验证我的登录表单【英文标题】:How to create a Bean to validate my login form using Spring Security 3.1.3 and JSF 【发布时间】:2012-11-07 19:14:21 【问题描述】:

在过去的几天里,我一直在疯狂地尝试使用 Spring Security 创建一个自定义登录页面,但是我没有找到一个可行的示例,也没有自己弄清楚如何使用 Spring 验证表单,相信我,我尝试了一切,我可能在谷歌上找到了所有相关的示例。

表单加载正常,一切就绪,当我单击“登录”按钮时,我需要让 Spring Security 对数据库的凭据进行身份验证。

让我把它分成几部分来解释。

所以,我有一个登录表单:

<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 验证凭据。

我的登录豆:

@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>

非常感谢任何帮助,我已经坚持了好几天了!!!

【问题讨论】:

how-to-validate-a-login-inside-a-bean-using-spring-securit 的精确副本和spring-custom-jsf-login-page-always-bad-credentials 的可能副本 【参考方案1】:

由于你想要primefaces的漂亮的ajax特性,你不能使用spring security提供的UsernamePasswordAuthenticationFilter。尝试直接调用AuthenticationManager,然后(The Authentication Manager and the Namespace 解释如何获取对它的引用)。

【讨论】:

您的意思是例如使用表单数据创建一个身份验证对象并尝试使用我在 applicationContext.xml 上设置的身份验证管理器对其进行身份验证?我曾经尝试过类似的事情,但我无法获得对经理的参考。我尝试在 appcontext.xml 中设置 alias="authenticationManager",然后使用 @Property(name="authenticationManaget") 获取它,但它返回 null,我试了又试,直到我放弃了。 是的。注入 authenticationManager 应该与注入任何其他 spring bean 没有什么不同。 (Annotation 中的错字可能是负责任的吗?使用@Property 注释是否适用于其他spring bean?顺便说一句,什么包定义了这个注释?) 难道不能通过bean重定向来实现吗?我的意思是这样的: public void login () //send redirect to "/portal/j_spring_security_check?j_username=" + login + "&j_password=" + passwd";【参考方案2】:

您不需要 bean 来验证 Spring 安全登录。

要自定义表单登录,form-login 元素是正确的位置,您确实可以将 JSF 页面指定为login-page。但是,该登录页面必须提供 spring 安全登录页面的预期行为。要了解这种行为,请阅读reference documentation of the form-login element,其中列出了以下可选参数:

登录处理网址

映射到 UsernamePasswordAuthenticationFilter 的 filterProcessesUrl 属性。默认值为“/j_spring_security_check”。

密码参数

包含密码的请求参数的名称。默认为“j_password”。

用户名参数

包含用户名的请求参数的名称。默认为“j_username”。

也就是说,spring security 期望凭据作为 http post 的请求参数传递到特定的 url。您的 JSF 表单违反了该约定:它被发布到了错误的 URL(因为您使用了 h:form,它希望 JSF 处理表单提交请求)。尝试改用 html &lt;form&gt;

关于如何从数据库中加载用户详细信息,参考文档在Using other Authentication Providers 中对此进行了介绍。

【讨论】:

首先,非常感谢您抽出宝贵时间。看,问题是,我不能使用
。我需要 因为如果我使用 ,(primefaces 按钮)将不起作用。这就像用于登录的 Primefaces 展示:primefaces.org/showcase/ui/dialogLogin.jsf 我需要按钮才能工作,这样我才能访问 doLogin 并检索 ajax 参数。在我的 bean 上需要这样的东西: if (#spring security check ok) auth = true; else auth = false 正如你所看到的,我也可以使用咆哮。你觉得麻烦不值得吗?你认为不值得麻烦吗??
你真的应该在你的问题中提到这样的限制。将提供另一个答案... 对不起,我希望得到一个 bean。无论如何,没有任何借口,你是对的。我在这里发布了一个解决方法(forum.springsource.org/…),我在其中尝试创建 2 个表单(1 个隐藏)并使用对话框表单中的数据填写隐藏表单并通过 javascript submit() 提交,但我发现它真的很不专业和懒惰。我真的很累,很想相信我应该离开它并使用表格......

以上是关于如何使用 Spring Security 3.1.3 和 JSF 创建一个 Bean 来验证我的登录表单的主要内容,如果未能解决你的问题,请参考以下文章

Grails spring-security-oauth-google:如何设置

认证和授权学习2:springboot中快速使用spring security

如何从spring security获取当前登录的用户对象?

Grails 3.3.9 spring security 3.2.3 spring security ui 3.1.2 无法更改用户数据

Spring Security使用原理解读

Grails spring security core 3.1.2 和 mongodb