Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为具有特定请求头的请求切换Spring安全性_Java_Spring_Spring Boot_Spring Security - Fatal编程技术网

Java 为具有特定请求头的请求切换Spring安全性

Java 为具有特定请求头的请求切换Spring安全性,java,spring,spring-boot,spring-security,Java,Spring,Spring Boot,Spring Security,我正在尝试切换/绕过/禁用Spring Security(身份验证和授权),以所有具有特定请求头的请求 例如,如果使用该请求头命中请求url,则应绕过Spring安全性,否则不应绕过它 为此,我使用以下requestMatchers Spring安全配置: @Override public void configure(WebSecurity web) throws Exception { web.ignoring() .antMatchers(HttpMethod.

我正在尝试切换/绕过/禁用Spring Security(身份验证和授权),以所有具有特定请求头的请求

例如,如果使用该请求头命中请求url,则应绕过Spring安全性,否则不应绕过它

为此,我使用以下requestMatchers Spring安全配置:

@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;
  }

}
谁能帮我找出我做错了什么?我的方法正确吗,或者我需要做些别的事情来实现这一点

编辑:
我在
beforeInvocation()
方法中的
org.springframework.security.access.intercept.AbstractSecurityInterceptor
类中遇到此异常,它试图从SecurityContextHolder获取身份验证对象
AbstractSecurityInterceptor
由其子类
MethodSecurityInterceptor
调用,该子类是从我的Spring控制器调用的,该控制器带有
@PreAuthorize

注释。我认为您的旁路运行良好。它跳过了支票

安全的授权检查部分从SecurityContext获取经过身份验证的对象,该对象将在请求通过spring安全过滤器时设置。

因此,当您跳过安全过滤器时,还未设置SecurityContext,因此会出现错误

您可以这样做,为您的自定义页眉大小写手动设置它

try {
    SecurityContext ctx = SecurityContextHolder.createEmptyContext();
    SecurityContextHolder.setContext(ctx);
    ctx.setAuthentication(event.getAuthentication());
} finally {
    SecurityContextHolder.clearContext();
}
编辑1:

回答所有的问题

但如果是这样的话,那么我想所有的GET call也应该有 失败,但我的GET呼叫工作正常

由于您添加了这条线路,所有GET呼叫都将从安全检查中跳过

.antMatchers(HttpMethod.GET, securityProps.getNoAuthGetPattern()).permitAll()
我可以在哪里添加您提到的代码?任何特定的过滤器或 其他地方

我在过滤器里做过类似的事情。 提及

查看答案中的
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);
}
你的答案是什么

我刚从一些答案中得到这个案例,现在找不到它的链接。但是您可以像这样或像上面那样设置身份验证

Authentication authentication = new PreAuthenticatedAuthenticationToken("system", null);
authentication.setAuthenticated(true);
context.setAuthentication(authentication);

谢谢你的回答。但如果是这样的话,我想所有的GET呼叫也应该失败,但我的GET呼叫工作正常。不管怎样,我在哪里可以添加你提到的代码?有什么特别的过滤器或其他地方吗?你的回答是什么?再次感谢。我要试一试。但是,如果我在HttpSecurity配置中为.requestMatchers(新的RequestHeaderRequestMatcher(“TEST-Header”,“TEST-VALUE”))添加permitAll(),就像为GET添加permitAll()一样,这仍然是因为它对GET有效,而不是对Header有效。它给了我同样的错误。更新了问题以供参考。这是很好的观点。。。。根据这一点,它应该允许。。。你从哪里得到例外?你能添加整个stacktrace吗?@dur我已经更新了问题的详细信息,我在哪里得到了异常。stacktraceElement数组的大小为0,因此堆栈跟踪不可用。刚刚得到我在问题中提到的异常消息。您的
GET
方法是否也用
PreAuthorize
注释?对于
get
methods.No,您应该会得到相同的异常。GET方法不使用预授权进行注释。这就是它使用
GET
方法的原因。如果对某些URL禁用Spring安全性,则无法对该URL使用方法安全性。您必须允许这些URL,而不是忽略URL。
Authentication authentication = new PreAuthenticatedAuthenticationToken("system", null);
authentication.setAuthenticated(true);
context.setAuthentication(authentication);