gpt4 book ai didi

java - 定义 antmatcher 时 Spring Security 默认表单登录页面失败

转载 作者:行者123 更新时间:2023-11-30 05:26:45 24 4
gpt4 key购买 nike

我在基于 Spring 5 表单的身份验证方面遇到问题。这只是目前的一个例子,因为我正在尝试隔离我遇到的问题。我的计划是将此配置包含在具有多种配置的较大项目中。下面的代码(可以在任何地方找到)按预期工作:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
auth.inMemoryAuthentication()
.passwordEncoder(passwordEncoder)
.withUser("user").password(passwordEncoder.encode("password")).roles("USER");
}

@Override
protected void configure(HttpSecurity http) throws Exception
{
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.and().csrf().disable();
}
}

添加antmatcher后以下代码不起作用:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
auth.inMemoryAuthentication()
.passwordEncoder(passwordEncoder)
.withUser("user").password(passwordEncoder.encode("password")).roles("USER");
}

@Override
protected void configure(HttpSecurity http) throws Exception
{
http.antMatcher("/test/**")
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.and().csrf().disable();
}
}

请注意,我只向此配置添加了一个 antmatcher。我只想将配置应用于/test/**。而且,在这种情况下,我没有对表单登录进行任何自定义操作,并且希望获得 Spring 默认表单。当然,在实际应用程序中我不会使用默认值,但这仅用于示例目的。当我获取以下 URL 时,我的第一个配置正确显示默认的内部 Spring 表单:http://localhost:8080/webapp/test/anything 。而且我可以成功验证。对于第二个配置,当发出相同的 URL 时,我收到 404 错误。

Spring security 实际上尝试重定向到: http://localhost:8080/webapp/login但是,该网址不存在。我确实尝试了以下更改:

@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/test/**").authorizeRequests().anyRequest().authenticated()
.and().formLogin().permitAll().loginPage("/test/login").loginProcessingUrl("/test/login")
.and().logout().logoutUrl("/test/logout").invalidateHttpSession(true).logoutSuccessUrl("/");
}

这也不起作用。我做了几次尝试,但都没有成功。定义 antmatcher 时是否可能禁用默认表单行为?

最佳答案

这是满足您要求的理想解决方案

@Override
protected void configure(HttpSecurity http) throws Exception
{
http
.requestMatchers().antMatchers("/test/**", "/customLoginPage", "/logout").and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/customLoginPage") //If you don't configure default is "/login"
.usernameParameter("userName").passwordParameter("password") //In case of custom form parameters
.defaultSuccessUrl("/app/user/dashboard") //If you don't configure default is "/"
.failureUrl("/login?error=true") //If you don't configure default is "/login?error"
.and().csrf().disable();
}

让我解释一下 Spring Security 如何处理的一些情况

情况1:

http.authorizeRequests()

等于

http.antMatcher("/**").authorizeRequests()

将定义代理过滤器,该过滤器的 url 模式将为 "/**"。使用这种类型的配置不会有任何问题,因为它是通配符。但在某些情况下,我们不想定义通配符 "/**" 那么我们应该正确配置 requestMatchers,否则我们最终会遇到很多不可猜测的问题。

情况2:

http.antMatcher("/test/**").authorizeRequests()

此处将添加 URL 模式 "/test/**" 的代理过滤器,带有/login 和/logout 的请求无法通过添加的过滤器。为了克服这个问题,应该使用 .requestMatchers() ,如下所示

http
.requestMatchers().antMatchers("/test/**", "/customLoginPage", "/logout")
.and().authorizeRequests()

这意味着具有过滤器映射的过滤器,如下所示

<filter-mapping>
<filter-name>/test/**</filter-name>
<url-pattern>/customLoginPage</url-pattern>
<url-pattern>/logout</url-pattern>
</filter-mapping>

您可以尝试一些基本示例(工作)from my github repository

关于java - 定义 antmatcher 时 Spring Security 默认表单登录页面失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58415927/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com