問題描述
我有帶有 thymeleaf 的 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.
你沒有為這個Adapter指定一個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(matchers -> matchers
.antMatchers("/api/**") // apply JWTSecurityConfig to requests matching "/api/**"
)
.authorizeRequests(authz -> authz
.anyRequest().authenticated()
)
.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
}
@Configuration
public class FormLoginConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests(authz -> authz
.anyRequest().authenticated()
)
.formLogin();
}
}
}
關于多個WebSecurityConfigurerAdapter
的更多細節,可以查看multiple HttpSecurity
部分.
For more details on multiple WebSecurityConfigurerAdapter
, you can see the multiple HttpSecurity
section in the Spring Security reference docs.
authorizeRequests()
和 requestMatchers()
的更多區別可以看這個 Stack Overflow 問題.
For more details on the difference between authorizeRequests()
and requestMatchers()
, you can see this Stack Overflow question.
這篇關于多個WebSecurityConfigurerAdapters:spring security中的JWT認證和表單登錄的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!