TL;DR
每次localhost:4200(通过cors过滤器)都会发出超文本传输协议请求localhost:8080它会丢失持有身份验证的会话范围bean,这基本上会使403的所有调用失败。不包括第一个超文本传输协议请求(它不支持Spring安全)
我有一个Spring Boot应用程序,它在localhost:8080中运行良好。我们正在其内部创建一个角度iframe,它也可以很好地工作(当部署在localhost:8080上时)
但是,当我们在localhost:4200(ng-serve)上执行此操作时,它将不起作用
它开始抱怨cors,所以我有以下配置,除了我添加的关于cors的所有配置。
@Configuration
@Profile({"dev"})
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class springDevConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception{
http.csrf().disable();
http.headers().frameOptions().sameOrigin();
http.headers().cacheControl().disable();
http.cors().configurationSource(corsConfigurationSource())
.and().authorizeRequests().anyRequest().permitAll();
}
@Bean
public CorsConfigurationSource corsConfigurationSource(){
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(
ImmutableList.of("http://localhost:4200"));
configuration.setAllowedMethods(Arrays.asList(
RequestMethod.GET.name(),
RequestMethod.POST.name(),
RequestMethod.OPTIONS.name(),
RequestMethod.DELETE.name(),
RequestMethod.PUT.name()));
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
我的会话bean相当简单
@Component
@SessionScope
public class UserSession {
//Holds the Authorities for the prePostEnabled
User user;
...
}
为了初始化用户,我向某个endpoint发出请求(不受保护),并在代码中执行类似的操作
...
User user = new User(id, "", authorities);
Authentication auth = new UsernamePasswordAuthenticationToken(
user, null,authorities));
SecurityContextHolder.getContext().setAuthentication(auth);
Usersession.setUser(user);
...
当我在localhost:8080上发出超文本传输协议请求时,后续的超文本传输协议请求具有相同的会话。
但是,当我尝试从localhost:4200向localhost:8080发出请求时,每个请求似乎都会获取不同的UserSession/或者打开一个新会话
(在所有受保护的endpoint上给我403)
到底发生了什么?为什么localhost:4200在向localhost:8080发出请求时,每次调用都要进行新会话?(为了解决此问题,应该更改哪些配置?)
增编1:如果我评论
@EnableGlobalMethodSecurity(prePostEnabled = true)
代码在localhost:4200上运行良好(我的意思是他不再有403个代码),但很可能仍然在每个请求中使用另一个会话范围bean
附录2:
它现在可以工作了
我所要做的就是将ssl放入ng serve配置中(它在本地主机上有:8080,但不是4200),JSessionId开始工作了!
你能再展示一下你是如何嵌入iframe的,以及什么服务于原始页面的吗?
似乎正在发生的是,您实际上是在未意识到的情况下提出跨域请求。8080和4200是不同的域,如果页面的一部分从一个域加载,而另一部分(即iframe)从另一个域加载,则构成跨域请求,并且一个域发送的cookie不会应用于另一个域的请求,因此会话范围不会共享。此外,如果您向加载原始页面的域以外的域发出Ajax请求,则默认情况下,除非您设置CORS,否则这些请求将被拒绝。这就解释了你为什么要这么做。
您必须确保页面的所有部分(包括iFrame和Ajax请求)都是从同一个域加载的,或者您有其他方法将会话附加到请求。通常,JSESSIONID cookie用于此目的。此cookie是否在初始响应中发送?
您通常有一个应用程序服务于前端,包括初始页面(例如4200上的应用程序),还有一个只响应API调用(例如8080上的应用程序),配置了CORS。通过这种方式,所有对后端的调用都是通过同一个域完成的,cookie可以正常应用。
我需要确保给定的 bean 是使用会话范围定义的。 我知道我可以使用或,其中是我的(Web)Application Context,但是,没有。 如果你想知道为什么我需要这样的东西,请检查这个问题。 相关:我可以以编程方式确定Spring bean是否不是单例吗?
问题内容: 这是我的工作方式 然后在 假设用户名是。然后,如果单击,将设置为Peter的用户对象,然后重定向到配置文件页面,该页面现在从中呈现信息。我只想使用创建相同的效果,因此想到了GET请求。所以我这样做 然后该方法就返回 剩下的就是创建一个servlet,捕获该,查询数据库以获取设置为重定向的对象。这是我的servlet 现在我有了,如何访问会话bean来查询数据库中的,然后访问受管Bean
我正在尝试使用Hazelcast分布式缓存来复制带有Spring Boot&Spring Security的HTTP会话,但无法进行设置(不过,简单的缓存复制工作良好,我已经通过在一个应用程序节点的map中设置一些值并尝试在其他集群节点上获得它来验证了这一点)。 我已经通过网页上的东西,但不幸的是,我无法设置这一点。应用程序在集群中运行时,在一个节点上登录后,我没有在其他节点上获取会话对象(我正在
问题内容: 有状态会话bean和HTTP会话之间有什么关系吗?我们将需要有状态会话Bean的用例是什么,而HTTP会话需要哪些用例。我可以将有状态会话Bean公开为静态Web服务吗? 问题答案: HTTP是一种无状态协议, 这意味着 它是服务器和客户端之间的实际传输协议- 是“无状态的, 因为它在调用之间不记得任何东西。 现在,首先阅读一下什么是HTTPSession和什么是Session Bea
我的REST API使用Spring会话和Spring Security性,但是当我通过一个简单的过滤器启用CORS时遇到了一个问题。 如果我通过http代理使用相对URI(映射http://xxxx/api 对于客户端应用程序中的/api),它运行良好。 如果我直接使用完整的URL,我在使用CORS时遇到了一个问题,它无法获取会话信息,下面是Spring Security日志 我正在使用Spri
我正在使用Spring Boot、Spring Security性和spring会话(redis)构建spring REST web应用程序。我正在使用SpringCloud和zuul代理按照网关模式构建一个云应用程序。在这个模式中,我使用spring会话来管理redis中的HttpSession,并使用它来授权我的资源服务器上的请求。当执行更改会话权限的操作时,我希望更新该对象,以便用户不必注销