首页 > 解决方案 > 不使用 Spring 安全性和 jsf 自定义登录调用 JSF bean 方法

问题描述

我知道我要问的是广泛讨论的话题,但我仍然卡在一个点上,无法弄清楚出了什么问题。

将 jsf 与 spring security 一起使用时,我的 bean 方法不会通过自定义登录表单调用。

这是我的 SecurityConfig 类-

    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    // require all requests to be authenticated except for the resources
    http.authorizeRequests().antMatchers("/javax.faces.resource/**")
        .permitAll().anyRequest().authenticated();
   // login
   http.formLogin().loginPage("/login.xhtml").permitAll()
       .failureUrl("/login.xhtml?error=true");
   // logout
   http.logout().logoutSuccessUrl("/login.xhtml");
   // not needed as JSF 2.2 is implicitly protected against CSRF
   http.csrf().disable();
   }

   @Autowired
   public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
   auth
        .inMemoryAuthentication()
        .withUser("pratik123").password("{noop}pratik123").roles("USER");
   }

自定义登录页面 - login.xhtml

<div class="col-sm height-100" style="background-color: #fff;">
    
    <div class="card margin-top-bottom-20">
                <div class="card-header">
                    <h3>Sign In</h3>
                </div>
                <div class="card-body">
                    <h:form prependId="false">
                    
                        <p:messages id="messages" showDetail="false" closable="true">
                            <p:autoUpdate />
                        </p:messages>                           
                        
                        <div class="input-group form-group">
                            <div class="input-group-prepend">
                                <span class="input-group-text"><!-- <i class="fas fa-key"></i> --></span>
                            </div>
                            <p:inputText id="username" required="true" placeholder="User Name" 
                                    label="User name" class="form-control" value="#{loginBeanNew.userName}"
                                    requiredMessage="Username may not be empty.">
                            </p:inputText>
                            
                        </div>
                        <div class="input-group form-group">
                            <div class="input-group-prepend">
                                <span class="input-group-text"><i class="fas fa-key"></i></span>
                            </div>
                            <p:password id="password" required="true" placeholder="Password" 
                                    label="Password" class="form-control"  value="#{loginBeanNew.userPassword}"
                                    requiredMessage="Password may not be empty.">
                            </p:password>
                        </div>
                        
                        <div class="form-group">
                            <h:commandButton id="login" value="Login" update="messages" class="btn float-left login_btn mt-3" 
                                            action="#{loginBeanNew.login}" ajax="false" />                              
                        </div>
                    </h:form>
                </div>
                <div class="card-footer">
                    <div class="d-flex justify-content-center links">
                        Don't have an account?
                        <p:commandLink styleClass="link_blue font-size-16 ml-2" action="#{registrationBean.registerNewUser}" immediate="true">
                            <h:outputText value=" Sign Up"/>
                        </p:commandLink>
                    </div>
                    <div class="d-flex justify-content-center links">
                        OR Sign In as Guest User
                        <p:commandLink styleClass="link_blue font-size-16 ml-2" action="#{guestUserBean.redirectToGuestUserPage}" immediate="true">
                            <h:outputText value=" Guest User Login"/>
                        </p:commandLink>
                    </div>
                </div>
            </div>
    
</div>

Bean - LoginBeanNew

@Log4j2
@SessionScoped
@Component(value = "loginBeanNew")
@ManagedBean
@Named
@Getter
@Setter
@Join(path = "/login", to = "/login.xhtml")
public class LoginBeanNew implements Serializable { 

public String login() {
    
    System.out.println("login method called.");
    System.out.println(this.getUserName());
    System.out.println(this.getUserPassword());
    
    ... Some more code 

}

}

和 web.xml

    <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
version="3.1">
<welcome-file-list>
    <welcome-file>home.html</welcome-file>
    <welcome-file>default.html</welcome-file>
</welcome-file-list>

<context-param>
    <param-name>primefaces.PRIVATE_CAPTCHA_KEY</param-name>
    <param-value>YOUR_PRIVATE_KEY</param-value>
</context-param>
<context-param>
    <param-name>primefaces.PUBLIC_CAPTCHA_KEY</param-name>
    <param-value>YOUR_PUBLIC_KEY</param-value>
</context-param>

<context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
</context-param>

<!-- Comment removed -->
<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<!-- <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> -->
<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener
    </listener-class>
</listener>
<!-- Comment removed -->

<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>
        org.springframework.web.filter.DelegatingFilterProxy
    </filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

</web-app>

而且,我没有从日志中发现太多,为什么不调用 bean 方法。

- 一些变化 -

在对安全配置进行一些更改时,我设法调用了 bean 方法,但默认情况下是登录页面身份验证。

安全配置更改 -

    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
protected void configure(HttpSecurity http) throws Exception {
    
    http
    .cors()
    .and()
    .csrf().disable()
    .authorizeRequests()
        .antMatchers("/css/**", "/js/**", "/images/**", "/javax.faces.resource/**", "/login.xhtml").permitAll()
    .anyRequest().authenticated().and().httpBasic();

}

    @Bean
public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("*"));
    configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
    configuration.setAllowedHeaders(Arrays.asList("authorization", "content-type", "x-auth-token"));
    configuration.setExposedHeaders(Arrays.asList("x-auth-token"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

    @Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth
            .inMemoryAuthentication()
            .withUser("pratik123").password("{noop}pratik123").roles("USER");
}

}

在调用 bean 方法的配置方法中使用上述代码,我想使用自定义登录而不是手动提供默认登录凭据。任何人都知道如何做到这一点?或者我的第一个方法对我的第一个 SecurityConfig 类是正确的。如果是这样,那么我如何使用自定义登录调用我的登录 bean 方法。提前致谢。

标签: jsfspring-security

解决方案


推荐阅读