带有Spring Boot的Spring Security:将基本身份验证与JWT令牌身份验证混合 [英] Spring Security with Spring Boot: Mix Basic Authentication with JWT token authentication

查看:187
本文介绍了带有Spring Boot的Spring Security:将基本身份验证与JWT令牌身份验证混合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让Spring Security的基本身份验证与JWT令牌身份验证并存,但没有成功.我已经为我的Web控制台和JWT实现了基本身份验证,以保护许多API端点.这是我的配置:

I am trying to get Spring Security's basic authentication to work side by side with JWT token authentication with no success. I have implemented basic authentication for my web console and JWT to secure a number of API endpoints. Here's my config:

@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MultiHttpSecurityConfig {

@Autowired
private UserDetailsService userDetailsService;    

@Autowired
public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
    authenticationManagerBuilder
            .userDetailsService(this.userDetailsService)
            .passwordEncoder(bCryptPasswordEncoder());
}

@Bean
public PasswordEncoder bCryptPasswordEncoder() {
    return new BCryptPasswordEncoder();
}

/**
 * 
 * API Security configuration
 *
 */
@Configuration
@Order(1) 
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter{

    @Bean
    public JwtAuthenticationTokenFilter authenticationTokenFilterBean() throws Exception {
        return new JwtAuthenticationTokenFilter();
    }

    @Autowired
    private JwtAuthenticationEntryPoint unauthorizedHandler;

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity   
            .csrf().disable()
            .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()                
            // don't create session
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
            .authorizeRequests().antMatchers("/api/**","/refresh/**").authenticated()
            .antMatchers("/auth/**").permitAll().anyRequest().authenticated();               
        // Custom JWT based security filter
        httpSecurity.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
        // disable page caching
        httpSecurity.headers().cacheControl();
    }
}

/**
 * 
 * Form login security configuration
 *
 */
@Configuration
public static class FormLoginWebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private ConsoleAuthenticationEntryPoint consoleAuthenticationEntryPoint;

    @Override
    protected void configure(HttpSecurity http) throws Exception {          
        http.httpBasic().and().exceptionHandling().authenticationEntryPoint(
                consoleAuthenticationEntryPoint).and()
         .authorizeRequests().antMatchers("/console/**").authenticated()
         .antMatchers(HttpMethod.GET,
                    "/*.html",
                    "/favicon.ico",
                    "/**/*.html",
                    "/**/*.css",
                    "/**/*.js").permitAll()
         .anyRequest().authenticated()
         .and()
         .formLogin().defaultSuccessUrl("/console/home")
         .loginPage("/console/login")
         .permitAll()
         .and()
         .logout()
         .permitAll();
        http.csrf().disable();
    }
}

}

我注意到我用Order(1)注释的配置是Spring Security选择的配置,而另一配置被完全忽略了.像上面的配置一样,如果我尝试访问/console/login,则会出现401错误. 任何帮助将不胜感激.

I have noticed that the configuration I annotate with Order(1) is the one that is picked by Spring Security and the other is completely ignored. Like in the above config, I get 401 error if I try to access /console/login. Any help would be much appreciated.

推荐答案

之所以如此,是因为ApiWebSecurityConfigurationAdapterFormLoginWebSecurityConfig都不使用antMatcher().这意味着即使以后使用antMatchers(),这两个安全配置也将处理所有路径.因此,具有最低顺序(@Order(1))的配置将处理所有操作,而其他配置则不执行任何操作.

The reason why is because neither ApiWebSecurityConfigurationAdapter nor FormLoginWebSecurityConfig uses the antMatcher(). This means that both security configurations will handle all paths, even though you're using antMatchers() afterwards. Due to this, the configuration with the lowest order (@Order(1)) will handle everything, while the other one will do nothing.

文档:

http.antMatcher声明此HttpSecurity仅适用于以/api/

The http.antMatcher states that this HttpSecurity will only be applicable to URLs that start with /api/

因此,要解决此问题,您必须将antMatcher置于您的一种配置(或两种配置)中.例如,如果仅将表单登录名应用于/console/login/console/home,则可以将配置更改为:

So, to fix this problem, you have to povide an antMatcher to one of your configurations (or both). For example, if the form login should only be applied to /console/login and /console/home, you could change the configuration to:

@Override
protected void configure(HttpSecurity http) throws Exception {          
    http
        .antMatcher("/console/**") // Add this
        .httpBasic().and()
        .exceptionHandling().authenticationEntryPoint(consoleAuthenticationEntryPoint).and()
        .authorizeRequests().antMatchers("/console/**").authenticated()
        .antMatchers(HttpMethod.GET,
                "/*.html",
                "/favicon.ico",
                "/**/*.html",
                "/**/*.css",
                "/**/*.js").permitAll()
        .anyRequest().authenticated().and()
        .formLogin().defaultSuccessUrl("/console/home")
        .loginPage("/console/login").permitAll().and()
        .logout().permitAll().and() // Make sure to use .and() to add the .csrf()
        .csrf().disable();
}

有关此主题的另一本好书是这个问题:何时使用Spring Security`s antMatcher()?

Another good read about this topic is this question: When to use Spring Security`s antMatcher()?

请注意,您不应该像添加.csrf().disable()那样两次使用http构建器,就像我在上面的代码中所做的那样,将其添加到其他构建器中.

Please note that you shouldn't use the http builder twice like you did to add the .csrf().disable(), add it to the other builder like I did in the code above.

另外请注意,您可能必须更改订单.您应该以最详细的antMatcher()(在这种情况下为FormLoginWebSecurityConfig)对配置进行订购.

Also be aware that you'll likely have to change the order. You should put the order on the configuration with the most detailed antMatcher(), in this case FormLoginWebSecurityConfig.

这篇关于带有Spring Boot的Spring Security:将基本身份验证与JWT令牌身份验证混合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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