Spring Boot with Spring Boot:将基本身份验证与JWT令牌身份验证相结合[复制]
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot with Spring Boot:将基本身份验证与JWT令牌身份验证相结合[复制]相关的知识,希望对你有一定的参考价值。
这个问题在这里已有答案:
我试图让Spring Security的基本身份验证与JWT令牌身份验证并行工作但没有成功。我已经为我的Web控制台和JWT实现了基本身份验证,以保护许多API端点。这是我的配置:
@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错误。任何帮助将非常感激。
原因是因为ApiWebSecurityConfigurationAdapter
和FormLoginWebSecurityConfig
都不使用antMatcher()
。这意味着即使您之后使用antMatchers()
,这两种安全配置都将处理所有路径。因此,具有最低阶(@Order(1)
)的配置将处理所有内容,而另一个配置将不执行任何操作。
这也在docs中提到:
http.antMatcher
声明此HttpSecurity
仅适用于以/api/
开头的网址
因此,要解决此问题,您必须将antMatcher
添加到您的某个配置(或两者)。例如,如果表单登录只应用于/console/login
和/console/home
,则可以将配置更改为:
@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();
}
关于这个主题的另一个好读物是这个问题:When to use Spring Security`s antMatcher()?
请注意,您不应像使用http
构建器那样添加.csrf().disable()
,将其添加到其他构建器,就像我在上面的代码中所做的那样。
另请注意,您可能需要更改订单。您应该在配置中使用最详细的antMatcher()
,在本例中为FormLoginWebSecurityConfig
。
以上是关于Spring Boot with Spring Boot:将基本身份验证与JWT令牌身份验证相结合[复制]的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot with Spring Data JPA - Concept
《Pro Spring Boot 2》第五章:Data Access with Spring Boot