多个WebSecurityConfigurerAdapters:Spring Security中的JWT身份验证和表单登录 [英] Multiple WebSecurityConfigurerAdapters: JWT authentication and form login in spring security

查看:51
本文介绍了多个WebSecurityConfigurerAdapters:Spring Security中的JWT身份验证和表单登录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有百里香的Spring Boot应用程序.我正在使用spring security formLogin方法来提高安全性,现在我只需要为某些API添加JWT.

I have spring boot app with thymeleaf. I am using spring security formLogin method for security and now I need to add JWT for only some APIs.


@EnableWebSecurity
public class SecurityConfigurations {
    @Autowired
    UserDetailsServiceImpl userDetails;

    @Bean
    DaoAuthenticationProvider provider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setPasswordEncoder(encoder());
        provider.setUserDetailsService(userDetails);
        return provider;
    }

    @Bean
    PasswordEncoder encoder() {
        return new BCryptPasswordEncoder();
    }

    @Configuration
    @Order(1)

    public class JWTSecurityConfig extends WebSecurityConfigurerAdapter {

        @Autowired
        private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;

        @Autowired
        private JwtRequestFilter jwtRequestFilter;

        @Autowired
        DaoAuthenticationProvider provider;

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.authenticationProvider(provider);
        }

        @Bean
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }

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

            httpSecurity.csrf().disable()

                    .authorizeRequests().antMatchers("/api/user/authenticate").permitAll()

                    .antMatchers("/api/user/**").hasRole("USER")
                    .and().
                    exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and().sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

            // Add a filter to validate the tokens with every request
            httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
        }
    }

    @Configuration
    public static class FormLoginConfigurationAdapter extends WebSecurityConfigurerAdapter {
        @Autowired
        DaoAuthenticationProvider provider;

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.authenticationProvider(provider);
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().antMatchers("/admin/admins**").hasAnyRole("SADMIN").antMatchers("/admin/**")
                    .hasAnyRole("ADMIN", "SADMIN", "WADMIN").antMatchers("/rest/**")
                    .hasAnyRole("ADMIN", "SADMIN", "WADMIN", "USER").antMatchers("/user/**").hasAnyRole("USER")
                    .anyRequest().permitAll().and().formLogin().loginPage("/sign-in-up")
                    .loginProcessingUrl("/signInProcess").usernameParameter("phone").and().logout()
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/")
                    .invalidateHttpSession(false).and().csrf().disable().cors();

        }
    }

}

通过执行此JWT可以按我的要求正常工作,但是formlogin已停止并调用"/signInProcess".现在给404:

by doing this JWT is working fine as just I need but the formlogin has stopped and calling "/signInProcess" now give 404:

注意::如果我更改订单并设置formLogin @order(1),它将再次起作用,但是当然将不起作用.

NOTE: if I change the order and make formLogin @order(1) it works again but of course will not work.

我也试图像这样将它们结合起来,现在它们都可以正常工作,但是如果JWT身份验证错误将返回formlogin thymeleaf错误页面,则出现异常处理问题:

Also I tried to combine them both like this now it is both works fine but the problem with exception handling if the JWT authentication error will return formlogin thymeleaf error page :

@Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().antMatchers("/admin/admins**").hasAnyRole("SADMIN").antMatchers("/admin/**")
                    .hasAnyRole("ADMIN", "SADMIN", "WADMIN").antMatchers("/rest/**")
                    .hasAnyRole("ADMIN", "SADMIN", "WADMIN", "USER").antMatchers("/user/**").hasAnyRole("USER")
                    .antMatchers("/api/user/authenticate").permitAll()
                    .antMatchers("/api/user/**").hasRole("USER")
                    .anyRequest().permitAll().and().formLogin().loginPage("/sign-in-up")
                    .loginProcessingUrl("/signInProcess").usernameParameter("phone").and().logout()
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/")
                    .invalidateHttpSession(false).and().csrf().disable().cors();
            
            http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);

        }

任何使这项工作可行的建议.谢谢.

any suggestions to make this work. thank you.

推荐答案

您的 WebSecurityConfigurerAdapters 将按顺序处理传入的请求.
由于 JWTSecurityConfig @Order(1)进行注释,因此它将首先处理请求.

Your WebSecurityConfigurerAdapters will process the incoming requests in order.
Since JWTSecurityConfig is annotated with @Order(1) it will process the requests first.

您尚未为此适配器指定 antMatcher ,因此它将匹配所有请求.
这意味着请求将永远不会到达 FormLoginConfigurationAdapter ,因为 JWTSecurityConfig 将它们全部匹配.

You have not specified a antMatcher for this Adapter, so it will match all requests.
This means that a request will never reach FormLoginConfigurationAdapter, since JWTSecurityConfig matches them all.

如果希望 JWTSecurityConfig 仅适用于某些请求,则可以在安全配置中指定 antMatcher .
下面是一个示例:

If you want JWTSecurityConfig to only apply to certain requests, you can specify an antMatcher in your security configuration.
Below is an example:

@EnableWebSecurity
public class SecurityConfigurations {

    @Configuration
    @Order(1)
    public class JWTSecurityConfig extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
           http
              .requestMatchers()
                  .antMatchers("/api/**") // apply JWTSecurityConfig to requests matching "/api/**"
              .authorizeRequests()
                  .anyRequest().authenticated()
              .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
        }
    }

    @Configuration
    public class FormLoginConfigurationAdapter extends WebSecurityConfigurerAdapter {

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

有关多个 WebSecurityConfigurerAdapter 的更多详细信息,请参阅

For more details on multiple WebSecurityConfigurerAdapter, you can see the multiple HttpSecurity section in the Spring Security reference docs.

有关 authorizeRequests() requestMatchers()之间的区别的更多详细信息,请参见

For more details on the difference between authorizeRequests() and requestMatchers(), you can see this Stack Overflow question.

这篇关于多个WebSecurityConfigurerAdapters:Spring Security中的JWT身份验证和表单登录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆