Spring Security with Spring Boot:将基本身份验证与 JWT 令牌身份验证混合使用

编程入门 行业动态 更新时间:2024-10-27 20:38:01
本文介绍了Spring Security with Spring Boot:将基本身份验证与 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.

推荐答案

原因是因为ApiWebSecurityConfigurationAdapter和FormLoginWebSecurityConfig都没有使用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.

docs 中也提到了这一点:

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`santMatcher()?

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 Security with Spring Boot:将基本身份验证与 JWT 令牌身份验证混合使用

本文发布于:2023-10-28 20:04:13,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1537638.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:身份验证   令牌   Security   Spring   JWT

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!