我正在尝试在iframe
中启用我的Sping Boot 网站。我有安全配置、请求过滤器、表单登录和OAuth2。我的表单登录在浏览器中运行良好,但当我从iframe
登录时,我可以看到从浏览器登录的相同用户的JSESSIONID
是null
。iframe
的日志:
UsernamePasswordAuthenticationToken [Principal=test@example.com, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[ROLE_USER]]
浏览器日志:
[Authentication=UsernamePasswordAuthenticationToken [Principal=test@example.com, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=04E5DB0982A859E5C215294EF96814FD], Granted Authorities=[ROLE_MANAGER, ROLE_USER]]]
下面是我的安全配置:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.cors().disable()
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/app_resources/**", "/signup", "/favicon.ico", "/login", "/logout", "/signup",
"/oauth2/authorization/**", "/pages/**", "/login/oauth2/code/**", "/login/oauth2/code/**",
"/product/authenticate", "/cdnjs.cloudflare.com/**").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.addFilterBefore(securityFilter, UsernamePasswordAuthenticationFilter.class)
.formLogin(form -> form
.loginPage("/auth")
.defaultSuccessUrl("/index")
.failureHandler(authenticationfailure())
.successHandler(new AuthSuccessHandler()).permitAll()
)
.logout(out -> out
.logoutUrl("/logout")
)
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.and()
.authenticationProvider(authProvider())
.oauth2Login()
.loginPage("/auth")
.defaultSuccessUrl("/homesuccess")
.successHandler(new AuthSuccessHandler());
http
.headers()
.frameOptions().disable();
return http.build();
}
下面是我的AuthenticationSuccesHandler
:
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
System.out.println("onAuthenticationSuccess >>>>>>>>>>>>>>"+authentication.toString());
request.getSession(false).setMaxInactiveInterval(604800);
RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
redirectStrategy.sendRedirect(request, response, "/");
}
不太确定iframe
内部出了什么问题。我可以看到我的登录页面,我可以看到AuthennticationSuccessHandler
中的用户密码令牌对象,但在将其重定向到 Jmeter 板后,安全过滤器中的主体对象突然变成了null
。
MVC配置:
@EnableWebMvc
@Configuration
public class MvcConfig implements WebMvcConfigurer{
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
VersionResourceResolver versionResolver = new VersionResourceResolver().addContentVersionStrategy("/**/*.js",
"/**/*.css", "/**/*.png");
registry.addResourceHandler("/app_resources/**", "/favicon.ico", "/firebase-messaging-sw.js", "/manifest.json",
"/salesken.png")
.addResourceLocations("/assets/js/",
"/assets/css/","/assets/img/","/")
.setCacheControl(CacheControl.maxAge(1, TimeUnit.MINUTES)).resourceChain(true)
.addResolver(versionResolver);
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_JSON);
}
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setPrefix("pages/");
bean.setSuffix(".jsp");
return bean;
}
}
即使我尝试将身份验证对象放入会话中,也没有设置此对象,其值在请求过滤器中为null
。
1条答案
按热度按时间zaq34kh61#
Chrome使用“Lax”作为default same-site cookie policy。
要在Sping Boot 2.5.0打开的情况下通过将SameSite标志设置为none来修复此问题,请添加以下内容:
仅适用于https,因为cookie必须是安全的。Sping Boot 会话cookie已经是httpOnly。
Sping Boot 2.5.0之前版本没有CookieSameSiteSupplier,因此必须创建以下内容。需要Spring Boot v2.1.0.RELEASE及更高版本。
具有以下依赖关系:
要在Tomcat上执行此操作-从8.5.42+. Edit %TOMCAT_HOME%/conf/context.xml开始,更新以下行中的CookieProcessor元素,例如在HTTP响应头的set-cookie中设置SameSiteCookies。
因为你正在编辑
%TOMCAT_HOME%/conf/context.xml
,它会对所有安装的webapps都这样做。为了避免这种情况,你需要破解META-INF文件夹,创建一个context.xml,并把上面的代码片段放进去。