将 JSF 登录页面与 Spring 安全性集成

Integrate a JSF login page with Spring Security

I´m trying to integrate a JSF web application with Spring Security.

Currently I'm logging in through a method: authenthicating inside this method and redirecting to the destination page based on the user.

登录页面(login.xhtml):

 <h:form id="login">
   <h:outputLabel for="email" value="E-mail: "/> 
   <p:inputText id="email" value="#{loginManagedBean.usuario.email}" required="true"/>
   <p:message for="email"/>

   <h:outputLabel for="pass" value="Contraseña: "/>                
   <p:password id="pass" value="#{loginManagedBean.usuario.password}" required="true"/>
   <p:message for="pass"/>

   <!-- <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> -->

   <p:commandButton value="Login" update="@form" action="#{loginManagedBean.autenticar()}"/>
 </h:form>

loginManagedBean.autenticar()(认证和重定向的方法):

How can I replace this page and method to work with SpringSecurity?

SpringSecurityConfig:

@Override
protected void configure(HttpSecurity http) throws Exception {

    //.csrf() is optional, enabled by default, if using WebSecurityConfigurerAdapter constructor
    // Have to disable it for POST methods:
    // 
    http.csrf().disable();

    // Logout and redirection:
    // 
    http
            .logout()
            .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .deleteCookies("JSESSIONID")
            .invalidateHttpSession(true)
            .logoutSuccessUrl("/login.xhtml");

    http
            .authorizeRequests()
            //Permit access for all to error and denied views
            .antMatchers("/WEB-INF/errorpages/general.xhtml", "/WEB-INF/errorpages/accessDenied.xhtml", "/WEB-INF/errorpages/expired.html", "/login.xhtml")
            .permitAll()
            // Only access with admin role
            .antMatchers("/admin/**")
            .hasRole("ADMIN")
            //Permit access only for some roles
            .antMatchers("/alumno/**")
            .hasRole("ALUMNO")
            //Permit access only for some roles
            .antMatchers("/profesor/**")
            .hasRole("PROFESOR")
            //If user doesn't have permission, forward him to login page
            .and()
            .formLogin()
            .loginPage("/login.xhtml")
            .usernameParameter("login:email")
            .passwordParameter("login:pass")
            .loginProcessingUrl("/login") //
            .defaultSuccessUrl("/admin/homeAdmin.xhtml")
            .and()
            .exceptionHandling()
            .accessDeniedPage("/WEB-INF/errorpages/accessDenied.xhtml");
}

我不想使用 JSF 进行身份验证,而是使用普通的 HTML 表单(having configured 之前的身份验证入口点):

<form action="#{request.contextPath}/j_spring_security_check"
    method="post">
    <h:panelGrid styleClass="centered tight-grid" columns="2">
        <p:outputLabel>Usuario</p:outputLabel>
        <input type="text" id="username" name="username"
            required="required" />
        <p:outputLabel>Contraseña</p:outputLabel>
        <input type="password" id="password" name="password"
            required="required" />
    </h:panelGrid>
    <h:panelGrid>
        <button type="submit">
            <span class="ui-button-text">Login</span>
        </button>
    </h:panelGrid>
</form>

这将对您的 Spring 安全身份验证入口点执行 POST。然后,一旦用户登录,您就可以使用 AuthenticationSuccessHandler 或默认目标 url 重定向到您的 JSF 应用程序。

登录按钮操作应该像这样首先执行重定向并将流程传递给 spring 安全。

ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
RequestDispatcher dispatcher = ((ServletRequest) context.getRequest()).getRequestDispatcher("/login");
dispatcher.forward((ServletRequest) context.getRequest(), (ServletResponse) context.getResponse());
FacesContext.getCurrentInstance().responseComplete();