我的 Spring MVC Web 应用程序中有一个相当简单的 Spring Security 配置。我正在接收来自远程 Web 应用程序的 REST 请求,这些请求通过我的 preauth 过滤器进行了身份验证。我只是在请求中查找标头,如果存在,我返回该字符串值(即用户名)作为身份验证对象。这工作正常,当请求进来时,用户会得到身份验证。
无论出于何种原因,每当我尝试强制执行基于模式的安全性 antMatcher 或控制器方法注释的安全性时,都会导致客户端收到 CORS 错误。我必须保持访问完全开放,以允许在这个跨域环境中进行实际请求。
我的问题是,一段时间后,会话似乎到期了。当用户点击我的一个控制器并尝试从 Principal 对象中获取用户名时,我会收到 NullPointerException,因为 Principal 为空。一旦它过期,它看起来像 AnonymousAuthFilter 启动并让用户以匿名方式连接。
我假设我不想要一个完全无状态的身份验证会话,因为我也在使用 websockets 的会话,当我使用我的消息传递模板来“convertAndSendToUser”时,我需要提供用户名和 Spring 需要查找网络套接字会话。但是,我想强制安全链识别传入请求是否没有分配主体,以通过我的 PreAuthFilter 强制请求返回并重新建立会话。
这可能吗?
以下是我的安全配置文件中配置方法的简要说明:
@Override
protected void configure(HttpSecurity http) throws Exception {
// Create authentication providers and authentication manager
List<AuthenticationProvider> authenticationProviders = new ArrayList<>(1);
AuthenticationProvider authProvider = preAuthenticatedAuthenticationProvider();
authenticationProviders.add(authProvider);
AuthenticationManager authenticationManager = authenticationManager(authenticationProviders);
// Create the pre-authentication filter
MyPreAuthFilter myPreAuthFilter = myPreAuthFilter(authenticationManager);
myPreAuthFilter.setAuthenticationManager(authenticationManager);
// configure http security
http
.csrf().disable()
.headers().addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN))
.and()
.authenticationProvider(authProvider)
.addFilter(myPreAuthFilter)
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers("/stomp/**").permitAll()
.antMatchers("/**").permitAll();
}
更新:所以我刚刚在 http 对象上了解了这个方法:
.anonymous().disable()
但是,当我使用它时,我所有的 CORS 请求都会再次失败。我认为这个问题特别是预检 OPTIONS 请求。这不能被验证——它需要匿名访问。因此,我认为要从跨域身份验证中获得我想要的行为,我需要禁用匿名过滤器,但这样做会破坏能够执行跨域请求的关键租户之一。啊。有人知道如何为除 OPTIONS 之外的所有请求禁用匿名吗?