![](/img/trans.png)
[英]How to add jwt authendication header with all requests in spring security?
[英]Toggle Spring Security for the requests with particular Request Header
我試圖切換/旁路/禁用春季安全 (身份驗證和授權) 具有特殊請求頭中的所有請求 。
例如,如果使用該請求標頭命中一個請求URL,則應該繞過Spring Security,否則就不應該繞過Spring Security。
為此,我正在使用以下requestMatchers Spring Security配置:
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.GET)
.antMatchers(HttpMethod.OPTIONS)
.requestMatchers(new RequestHeaderRequestMatcher("TEST-HEADER","TEST-VALUE"));
}
我剩下的安全配置是:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity (prePostEnabled = true)
@ConditionalOnProperty (name = "security.enabled", havingValue = "true", matchIfMissing = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private SecurityProps securityProps;
@Autowired
private MyUserDetailsService myUserDetailsService;
@Autowired
private MyAuthenticationEntryPoint myAuthenticationEntryPoint;
@Autowired
private MyCORSFilter myCORSFilter;
public SecurityConfig() {
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf().disable()
.addFilterBefore(myCORSFilter, SessionManagementFilter.class)
.addFilterBefore(requestHeaderFilter(), RequestHeaderAuthenticationFilter.class)
.authenticationProvider(preauthAuthProvider())
.authorizeRequests()
.antMatchers(HttpMethod.GET, securityProps.getNoAuthGetPattern()).permitAll()
.antMatchers(HttpMethod.OPTIONS, securityProps.getNoAuthOptionsPattern()).permitAll()
.requestMatchers(new RequestHeaderRequestMatcher("TEST-HEADER","TEST-VALUE")).permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(myAuthenticationEntryPoint);
}
@Autowired
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(preauthAuthProvider());
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.GET)
.antMatchers(HttpMethod.OPTIONS)
.requestMatchers(new RequestHeaderRequestMatcher("TEST-HEADER","TEST-VALUE"));
}
public RequestHeaderAuthenticationFilter requestHeaderFilter() throws Exception {
RequestHeaderAuthenticationFilter requestHeaderAuthenticationFilter = new RequestHeaderAuthenticationFilter();
requestHeaderAuthenticationFilter.setPrincipalRequestHeader(MySecurityConstants.LOGIN_HEADER);
requestHeaderAuthenticationFilter.setAuthenticationManager(authenticationManager());
requestHeaderAuthenticationFilter.setExceptionIfHeaderMissing(false);
requestHeaderAuthenticationFilter.setAuthenticationFailureHandler(new AuthenticationFailureHandler() {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
if (exception instanceof MySecurityException) {
myAuthenticationEntryPoint.commenceMySecurityException(request, response, (MySecurityException) exception);
} else if (exception instanceof UsernameNotFoundException) {
myAuthenticationEntryPoint.commenceUsernameNotFoundException(request, response,
(UsernameNotFoundException) exception);
} else if (exception instanceof PreAuthenticatedCredentialsNotFoundException) {
myAuthenticationEntryPoint.commence(request, response, exception);
}
}
});
return requestHeaderAuthenticationFilter;
}
@Bean
public PreAuthenticatedAuthenticationProvider preauthAuthProvider() throws Exception {
PreAuthenticatedAuthenticationProvider authProvider = new PreAuthenticatedAuthenticationProvider();
authProvider.setPreAuthenticatedUserDetailsService(userDetailsServiceWrapper());
return authProvider;
}
@Bean
public UserDetailsByNameServiceWrapper<PreAuthenticatedAuthenticationToken> userDetailsServiceWrapper()
throws Exception {
UserDetailsByNameServiceWrapper<PreAuthenticatedAuthenticationToken> wrapper =
new UserDetailsByNameServiceWrapper<>();
wrapper.setUserDetailsService(ivyUserDetailsService);
return wrapper;
}
}
通過以上設置,我無法禁用/繞過Spring Security,並且遇到了AuthenticationCredentialsNotFoundException異常:
org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
誰能幫助我確定我做錯了什么? 我的方法正確嗎,或者我需要做其他事情才能做到這一點?
編輯:我在beforeInvocation()
方法的org.springframework.security.access.intercept.AbstractSecurityInterceptor
類中獲取此異常,嘗試從SecurityContextHolder獲取身份驗證對象。 AbstractSecurityInterceptor
由其子類MethodSecurityInterceptor
調用,該子類是從我的Spring控制器 (由@PreAuthorize
注釋)中@PreAuthorize
。
我認為您的旁路運行良好。 它跳過檢查。
安全性的授權檢查部分從SecurityContext獲取經過身份驗證的對象,當請求通過Spring安全性過濾器時將設置該對象。
因此,當您跳過安全過濾器時,尚未設置SecurityContext,因此錯誤
您可以執行以下操作為“自定義標題案例”手動進行設置
try {
SecurityContext ctx = SecurityContextHolder.createEmptyContext();
SecurityContextHolder.setContext(ctx);
ctx.setAuthentication(event.getAuthentication());
} finally {
SecurityContextHolder.clearContext();
}
編輯1:
回答所有查詢。
但是,如果真是這樣,那么我猜所有的GET調用也應該都失敗了,但是我的GET調用工作正常。
由於已添加此行,因此從安全檢查中跳過了所有GET調用。
.antMatchers(HttpMethod.GET, securityProps.getNoAuthGetPattern()).permitAll()
在哪里可以添加您提到的代碼? 任何特定的過濾器或其他地方?
我在過濾器中做了類似的事情。 在這里參考
查看Answer中的TokenAuthenticationFilter
類。 在哪里手動設置。
注意:它的JWT實現但值得參考
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (tokenHelper.validateToken(authToken, userDetails)) {
// create authentication
TokenBasedAuthentication authentication = new TokenBasedAuthentication(userDetails);
authentication.setToken(authToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
您的答案是什么事件?
我剛從Some Answer那里得到這種情況,現在找不到它的鏈接。 但是您可以像上面這樣設置setAuthentication
Authentication authentication = new PreAuthenticatedAuthenticationToken("system", null);
authentication.setAuthenticated(true);
context.setAuthentication(authentication);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.