简体   繁体   English

更改spring security中的登录服务URL

[英]Changing the login service URL in spring security

Hi I have implemented Spring security in my spring boot web application with JWT filters.嗨,我已经使用 JWT 过滤器在我的 Spring Boot Web 应用程序中实现了 Spring 安全性。 But the default authentication is happening at url http://localhost:8080/login .但是默认身份验证发生在 url http://localhost:8080/login How to change /login to some url I need like /rest/auth/login ?如何将/login更改为我需要的某些 url,例如/rest/auth/login

My WebSecurity class is我的网络WebSecurity类是

@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {

@Autowired
private UserDetailsService userDetailsService;

@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;

public WebSecurity( UserDetailsService userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder )
{
    this.userDetailsService = userDetailsService;
    this.bCryptPasswordEncoder = bCryptPasswordEncoder;
}

@Override
protected void configure( HttpSecurity http ) throws Exception
{
    http.cors().and().csrf().disable().authorizeRequests().antMatchers(HttpMethod.POST, "/rest/auth/**").permitAll()
            .antMatchers("/static/*").permitAll().antMatchers("/").permitAll()
            /* .anyRequest().authenticated() */.and()
            .addFilter(new JWTAuthenticationFilter(authenticationManager()))
            .addFilter(new JWTAuthorizationFilter(authenticationManager()));
}

@Override
public void configure( AuthenticationManagerBuilder auth ) throws Exception
{
    auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
}

@Override
public void configure( org.springframework.security.config.annotation.web.builders.WebSecurity web )
        throws Exception
{

    web.ignoring().antMatchers("/static/**");
}

@Bean
CorsConfigurationSource corsConfigurationSource()
{
    final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
    return source;
}
}

I have a login page in my resource folder under static directory.我的静态目录下的资源文件夹中有一个登录页面。 The way Spring security works is, when user sends userName and password from the form, client has to send those credentials to /login path in the server, so that spring security verifies those credentials and creates token. Spring security 的工作方式是,当用户从表单发送userNamepassword ,客户端必须将这些凭据发送到服务器中的/login路径,以便 spring security 验证这些凭据并创建令牌。 But I want to change that default path /login to /rest/auth/login但我想将默认路径/login更改为/rest/auth/login

You need to tweak the WebSecurityConfig.java and JWTAuthenticationFilter .您需要调整WebSecurityConfig.javaJWTAuthenticationFilter

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

    http.csrf().disable()

            .authorizeRequests()

            .antMatchers("/rest/noauth/**").permitAll()

            .antMatchers("/rest/login").permitAll()

            .antMatchers("/rest/logout").permitAll()

            .antMatchers("/src/**").permitAll()

            .antMatchers("/v2/api-docs/**", "/configuration/ui/**", "/swagger-resources/**",
                    "/configuration/security/**", "/swagger-ui.html/**", "/webjars/**")
            .permitAll()

            .anyRequest().authenticated()

            .and()

            .logout().addLogoutHandler(logoutHandler).logoutSuccessHandler(logoutSuccessHandler)
            .logoutUrl("/rest/logout")

            .and()

            .addFilterBefore(
                    new JWTAuthenticationFilter("/rest/login",
                    UsernamePasswordAuthenticationFilter.class)

            .addFilterBefore(new JWTAuthorizationFilter(authenticationManager(), authTokenModelRepository),
                    UsernamePasswordAuthenticationFilter.class);

    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

}

and make your JWTAuthenticationFilter extends AbstractAuthenticationProcessingFilter which has a constructor which takes the filterProcessingURl and I passed /rest/login as the parameter.并使您的JWTAuthenticationFilter扩展AbstractAuthenticationProcessingFilter ,它具有一个采用filterProcessingURl的构造函数,我将/rest/login作为参数传递。

public class JWTAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

private static final Logger LOGGER = LoggerFactory.getLogger(JWTAuthenticationFilter.class);

private AuthenticationManager authenticationManager;
private TokenService tokenService;
private UserModel credentials;

private RefreshTokenService refreshTokenService;
private AuthTokenModelRepository authTokenModelRepository;
private UserModelRepository userModelRepository;

public JWTAuthenticationFilter( String loginUrl, AuthenticationManager authenticationManager,
        TokenService tokenService, RefreshTokenService refreshTokenService,
        AuthTokenModelRepository authTokenModelRepository, UserModelRepository userModelRepository )
{
    super(new AntPathRequestMatcher(loginUrl));

}

After the above configuration, the JWTAuthenticationFilter will be executed for the request /rest/login .完成上述配置后,将针对请求/rest/login执行JWTAuthenticationFilter

In your AuthenticationFilter you can call setFilterProcessesUrl during construction, example:在您的 AuthenticationFilter 中,您可以在构造过程中调用setFilterProcessesUrl ,例如:

public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

   private AuthenticationManager authenticationManager;

   public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
      this.authenticationManager = authenticationManager;

      setFilterProcessesUrl("/api/v1/tokens"); // <--- like this
   }

   ...

Hope it helps.希望它有帮助。

Just to complement Jordy Baylac's answer: in Kotlin I was struggling how to set the filter once I'm injecting the dependencies via main constructor.只是为了补充Jordy Baylac 的回答:在 Kotlin 中,一旦我通过主构造函数注入依赖项,我就很难设置过滤器。 My solution was do something like this:我的解决方案是做这样的事情:

class AuthenticationFilter(
    authenticationManager: AuthenticationManager?,
    private var jwtUtilsComponent: JwtUtilsComponent,
) : UsernamePasswordAuthenticationFilter() {
    private val authManager: AuthenticationManager? = authenticationManager

    init {
        setFilterProcessesUrl("/${ApiProperties.BASE_PATH}/login")
    }
    
    // more code
}

then it worked very well.然后它工作得很好。

In the configure method try to add loginProcessungUrl() method.在 configure 方法中尝试添加loginProcessungUrl()方法。 You can set the value in the parameter您可以在参数中设置值

.addFilter(new JWTAuthorizationFilter(authenticationManager()))
.loginProcessingUrl(LOGIN_URL);

You need to provide the url to the login page and the url that would process the authentication.您需要提供登录页面的 url 和将处理身份验证的 url。 This can be done by overriding the method like this:这可以通过像这样覆盖方法来完成:

    @Override
    protected void configure( HttpSecurity http ) throws Exception
    {
        http.cors().and().csrf().disable().
        authorizeRequests().
        antMatchers(HttpMethod.POST, "/rest/auth/**").
        permitAll()           
       .antMatchers("/static/*").permitAll()  
       .antMatchers("/").permitAll()
       .and().formLogin().
       /*This is where the juice is*/
       loginPage("/login").loginProcessingUrl("/rest/auth/login")
       /* .anyRequest().authenticated() */.and()
       .addFilter(new JWTAuthenticationFilter(authenticationManager()))
       .addFilter(new JWTAuthorizationFilter(authenticationManager()));
        }

The loginPage("/login") can be replaced with the route to your static login page while the loginProcessingUrl is the url of the controller that processes your login logic. loginPage("/login") 可以替换为静态登录页面的路由,而 loginProcessingUrl 是处理登录逻辑的控制器的 URL。 Ensure that controllers exist for both /login and /loginProcesingUrl.确保 /login 和 /loginProcesingUrl 都存在控制器。

Modify "HttpSecurity", as follows, example:修改“HttpSecurity”,如下,示例:

@Override
protected void configure( HttpSecurity http ) throws Exception {
http.cors().and().csrf().disable().authorizeRequests().antMatchers(HttpMethod.POST, "/rest/auth/**").permitAll()
        .antMatchers("/static/*").permitAll().antMatchers("/").permitAll()
        /* .anyRequest().authenticated() */
        .and()
             .formLogin()
             .loginPage("/login")
             .loginProcessingUrl("/rest/auth/login")
             .permitAll()
        .and()
             .logout()
             .permitAll();
        .and()
             .addFilter(new JWTAuthenticationFilter(authenticationManager()))
             .addFilter(new JWTAuthorizationFilter(authenticationManager()));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM