如何在 Spring Security 中更改登录 URL

Posted

技术标签:

【中文标题】如何在 Spring Security 中更改登录 URL【英文标题】:How to change Login URL in Spring Security 【发布时间】:2018-09-10 00:33:30 【问题描述】:

我创建了一个提供用户身份验证的 API,它的登录操作由 Spring Security 在默认的 '/login' 路径上处理。

我想将此路径更改为 'api/v1/login'

这是我的安全配置:

http.cors().and().csrf().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests()
            .antMatchers("/h2-console/**/**").permitAll()
            .antMatchers(HttpMethod.POST,"/user/register").permitAll()
            .antMatchers("/user/activate").permitAll()
            .antMatchers("/user/reset-password").permitAll()
            .antMatchers("/user/reset-password").permitAll()
            .antMatchers("/admin/user").hasRole("ADMIN")
            .antMatchers("/roles").permitAll()
            .antMatchers("/user/**").hasRole("USER")
            .and()
            .formLogin().loginProcessingUrl("/api/v1/login")
            .and()
            .exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
            .and()
            .addFilterBefore(new ExceptionHandlerFilter(), UsernamePasswordAuthenticationFilter.class)
            .addFilter(new JwtAuthenticationFilter(authenticationManager()))
            .addFilter(new JwtAuthorizationFilter(authenticationManager(), jwtUserDetailService));

我已经添加了这一行来改变它:

.formLogin().loginProcessingUrl("/api/v1/login")

但它仍然在 '/login' 路径下工作。

“/api/v1/login”返回404。

有什么办法可以改吗?

Spring Boot 版本:2.0.0.RELEASE

【问题讨论】:

.loginProcessingUrl("/api/v1/login") 将覆盖 /login post url 到 /api/v1/login 您将在其中提交凭据 我正在通过邮递员发送帖子请求,它不会覆盖它,仍在为'/login'工作。 贴出你正在尝试的完整网址,你也可以分享邮递员的截图 @kakabali image.ibb.co/ksihH7/Screenshot_from_2018_03_31_09_20_21.png 你能检查一下你在/api/**下的网址是否都是安全的吗?如果是,则尝试从 /api/v1/login 中删除安全性并将 permitAll() 配置添加到此 url 【参考方案1】:

函数.loginProcessingUrl("/api/v1/login"),指定验证凭据的URL,验证用户名和密码的URL。

它只会覆盖 POST 类型的 /api/v1/login 的 url,而不是 GET

它不会将请求传递给 Spring MVC 和你的控制器

如需更多自定义,您可以查看FormLoginConfigurer

更新 v1

您能否也检查一下您在/api/** 下的网址是否都是安全的?

如果是,则尝试从 /api/v1/login 中删除安全性并将 permitAll() 配置添加到此 url

查看此帖子 - https://***.com/a/27471722/2600196。如果它对您的方案有帮助

UPDATE v2 - 这对这里的案例有所帮助

您没有正确发送用户名和密码,为此请参阅以下内容,在您的邮件中显示为BadCredentialsException。我在应用程序上启用了调试并且能够解决这个问题。

您需要将参数发布到url - http://localhost:8080/api/v1/login 如下(还附上了图片,邮递员的截图):-

标题: Content-Type=application/x-www-form-urlencoded

键值对中的参数(不是json格式,请参考图片):

username=player3
password=pass3

您可以在上面看到 index.html 的响应,如下所示:-

<a href="http://localhost:8080/other.html">test static resource</a>

您还需要自定义。

对于发送用户名和密码的 JSON 请求,您可以轻松进行的更改将是:-

@Override
protected void configure(HttpSecurity http) throws Exception 

    http.cors().and().csrf().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .authorizeRequests()
        .antMatchers("/h2-console/**/**").permitAll()
        .antMatchers(HttpMethod.POST,"/user/register").permitAll()
        .antMatchers("/user/activate").permitAll()
        .antMatchers("/user/reset-password").permitAll()
        .antMatchers("/user/reset-password").permitAll()
        .antMatchers("/admin/user").hasRole("ADMIN")
        .antMatchers("/roles").permitAll()
        .antMatchers("/user/**").hasRole("USER")
        //.and()
        //.formLogin().loginProcessingUrl("/api/v1/login") // not required any more
        .and()
        .exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
        .and()
        .addFilterBefore(new ExceptionHandlerFilter(), UsernamePasswordAuthenticationFilter.class)
        .addFilter(jwtAuthorizationFilter())
        .addFilter(new JwtAuthorizationFilter(authenticationManager(), jwtUserDetailService));
    
    http.headers().frameOptions().disable(); // its required for h2-console



public JwtAuthenticationFilter jwtAuthorizationFilter() throws Exception 
    JwtAuthenticationFilter jwtAuthenticationFilter = new JwtAuthenticationFilter(authenticationManager());
    jwtAuthenticationFilter.setFilterProcessesUrl("/api/v1/login");
    return jwtAuthenticationFilter;

不再需要代码.formLogin().loginProcessingUrl("/api/v1/login")

您还需要将成功和失败 url 添加到应用程序,并使您的登录 url 获取基于 json 的用户凭据,您需要跟进并需要做更多的事情,一些有用的参考 - https://***.com/a/19501060/2600196

【讨论】:

【参考方案2】:

你是extending org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter,它本身就是extendsorg.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter。在最后一个类中,有一个名为

的 setter

setFilterProcessesUrl

旨在做到这一点:

setFilterProcessesUrl

public void setFilterProcessesUrl(String filterProcessesUrl)

设置确定是否需要身份验证的 URL

参数:filterProcessesUrl

This 是指向该 javadoc 部分的链接

因此,在您的 WebSecurityConfigurerAdapter 中,您可以这样做:

@Bean 
public JWTAuthenticationFilter getJWTAuthenticationFilter()  
    final JWTAuthenticationFilter filter = new JWTAuthenticationFilter(authenticationManager()); 
    filter.setFilterProcessesUrl("/api/auth/login"); 
    return filter; 

然后在同一个类的配置方法中只引用它而不是创建新实例:

.addFilter(getJWTAuthenticationFilter

【讨论】:

以上是关于如何在 Spring Security 中更改登录 URL的主要内容,如果未能解决你的问题,请参考以下文章

成功登录后如何更新 Spring Security UserDetails impls?

Spring Security:添加“伪登录”以更改用户信息

如何自定义 Grails Spring Security REST 登录响应 HTTP 代码

登录时更改spring security中的用户名

spring security 改变 spring_security_login 表单

强制用户在 Spring Security 中更改过期密码