jsf - 不使用 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 方法。提前致谢。
解决方案
推荐阅读
- ios - 在 iOS 13/14 上删除应用程序时是否会擦除 UserDefaults?
- gitlab - 修复“贡献者”视图,以便正确合并具有不同用户名和/或地址的用户
- python - 使用 Python C Api 部分解析 args/kwargs
- python - 我的 Windows 机器无法通过 OSGeo4W 程序安装 PROJ 4.9.0。我应该怎么办?
- ios - 如何让 Firebase 应用预览页面打开应用?
- arrays - 确定数组的实际使用大小
- android - Jetpack Compose:禁用与 TextField 的交互
- iis - IIS 重定向规则到多个 500 错误页面
- python - 如何在 Django 中获取 URL 完整路径的字符串表示形式?
- c# - OpenSSL 中的 VC-WIN32-ONECORE 是什么意思?