我的应用程序目前使用Spring Session和Redis作为后端.
我搜索了Spring Session 的官方文档,但是在使用该模块时无法找到默认会话超时.
此外,我不知道如何在必要时更改默认超时.
有人可以建议吗?
查看Spring Boot文档,我只找到了使用Redis会话的示例,是否可以在没有 Redis的情况下使用它?
在我的Spring Boot基于1.4的应用程序中,我用来Spring Session将会话数据存储在数据库中JDBC.
这适用于默认会话.但是当我想添加一个新会话(通过添加?_s=1到应用程序URL)时,我得到以下异常:
java.lang.IllegalArgumentException: An invalid character [32] was present in the Cookie value
Run Code Online (Sandbox Code Playgroud)
这是什么问题?
编辑:请注意,我自己没有设置cookie值,Spring Session这样做.因此我无法分辨它试图设置的值.
完整的堆栈跟踪在这里:
java.lang.IllegalArgumentException: An invalid character [32] was present in the Cookie value
at org.apache.tomcat.util.http.Rfc6265CookieProcessor.validateCookieValue(Rfc6265CookieProcessor.java:160) ~[tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.tomcat.util.http.Rfc6265CookieProcessor.generateHeader(Rfc6265CookieProcessor.java:109) ~[tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.catalina.connector.Response.generateCookieString(Response.java:989) ~[tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.catalina.connector.Response.addCookie(Response.java:937) ~[tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.catalina.connector.ResponseFacade.addCookie(ResponseFacade.java:386) ~[tomcat-embed-core-8.5.4.jar:8.5.4]
at org.springframework.session.web.http.DefaultCookieSerializer.writeCookieValue(DefaultCookieSerializer.java:112) ~[spring-session-1.2.1.RELEASE.jar:na]
at org.springframework.session.web.http.CookieHttpSessionStrategy.onNewSession(CookieHttpSessionStrategy.java:213) ~[spring-session-1.2.1.RELEASE.jar:na]
at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:247) ~[spring-session-1.2.1.RELEASE.jar:na]
at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.access$100(SessionRepositoryFilter.java:214) ~[spring-session-1.2.1.RELEASE.jar:na]
at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryResponseWrapper.onResponseCommitted(SessionRepositoryFilter.java:202) ~[spring-session-1.2.1.RELEASE.jar:na]
at org.springframework.session.web.http.OnCommittedResponseWrapper.doOnResponseCommitted(OnCommittedResponseWrapper.java:226) ~[spring-session-1.2.1.RELEASE.jar:na]
at org.springframework.session.web.http.OnCommittedResponseWrapper.sendRedirect(OnCommittedResponseWrapper.java:126) ~[spring-session-1.2.1.RELEASE.jar:na]
at javax.servlet.http.HttpServletResponseWrapper.sendRedirect(HttpServletResponseWrapper.java:138) ~[tomcat-embed-core-8.5.4.jar:8.5.4]
at …Run Code Online (Sandbox Code Playgroud) 我在我的应用程序中使用Spring Security和Spring Session(v1.3.1).
我想使用SpringSessionBackedSessionRegistry作为我的会话注册表,使用Redis作为我的会话存储库.
SpringSessionBackedSessionRegistry的构造函数如下:
SpringSessionBackedSessionRegistry(FindByIndexNameSessionRepository<ExpiringSession> sessionRepository)
Run Code Online (Sandbox Code Playgroud)
Redis存储库RedisOperationsSessionRepository实现:
FindByIndexNameSessionRepository<org.springframework.session.data.redis.RedisOperationsSessionRepository.RedisSession>
Run Code Online (Sandbox Code Playgroud)
那么,如何能我构建的一个实例SpringSessionBackedSessionRegistry给出的实例RedisOperationsSessionRepository?
为什么SpringSessionBackedSessionRegistry的构造函数不是:
SpringSessionBackedSessionRegistry(FindByIndexNameSessionRepository<? extends ExpiringSession> sessionRepository)
Run Code Online (Sandbox Code Playgroud) 我最近升级到 Spring Security 6,发现使用 JS 或curl 的基本身份验证进行身份验证不再有效,但使用 Java 的 HttpClient 进行基本身份验证确实有效。我的目标是能够使用所有方法进行身份验证。
\n该应用程序使用 Java 17、Spring Security 6 和 Spring Session 3。它有一个“登录”端点,这只是一个方便的端点,预计将通过基本身份验证进行命中并创建会话,并且它返回一个 User 对象。会话 ID 应用于对其他端点的后续请求。
\n卷曲命令如下所示:
\n curl -kv --user admin:admin "https://localhost:9000/login"\nRun Code Online (Sandbox Code Playgroud)\nVS HttpClient 的配置如下并调用 HttpClient.get(loginUrl)
\nHttpClient.newBuilder()\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0.connectTimeout(Duration.ofSeconds(300))\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0.cookieHandler(new CookieManager())\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0.authenticator(new BasicAuthenticator(username, password))\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0.sslContext(createSsl())\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0.build();\n\npublic class BasicAuthenticator extends Authenticator {\n\n\xc2\xa0\xc2\xa0\xc2\xa0private PasswordAuthentication authentication;\n\n\xc2\xa0\xc2\xa0\xc2\xa0public BasicAuthenticator(String username, String password) {\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0authentication = new PasswordAuthentication(username, password.toCharArray());\n\xc2\xa0\xc2\xa0\xc2\xa0}\n\n\xc2\xa0\xc2\xa0\xc2\xa0@Override\n\xc2\xa0\xc2\xa0\xc2\xa0public PasswordAuthentication getPasswordAuthentication() {\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0return authentication;\n\xc2\xa0\xc2\xa0\xc2\xa0}\n}\nRun Code Online (Sandbox Code Playgroud)\n安全配置是下面的块...在升级到 SpringSecurity 6 时,我添加了 requireExplicitSave() 方法,我对此表示怀疑,因为我的麻烦在于保存会话,但添加的代码应该具有使用旧功能的 spring security 。
\nhttp\n\xc2\xa0\xc2\xa0\xc2\xa0.securityContext( securityContext -> securityContext.requireExplicitSave(false))\n\xc2\xa0\xc2\xa0\xc2\xa0.authorizeHttpRequests((authz) -> authz\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0.requestMatchers(openEndpoints).permitAll()\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0.anyRequest().authenticated()\n\xc2\xa0\xc2\xa0\xc2\xa0)\n\xc2\xa0\xc2\xa0\xc2\xa0.httpBasic()\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0.and()\n\xc2\xa0\xc2\xa0\xc2\xa0.csrf()\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0.disable()\n\xc2\xa0\xc2\xa0\xc2\xa0.exceptionHandling()\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0.accessDeniedHandler((req, …Run Code Online (Sandbox Code Playgroud) 我有一个项目,春节引导1.3.3 [其他的东西]和Redis的可配置管理会话,即@EnableRedisHttpSession.该应用程序运行良好,并定期将信息存储在Redis上.我面临的问题是,与文档所说的不同,无论我是否定义了server.session.timeout,Redis总是使用其注释属性的默认值(maxInactiveIntervalInSeconds),即:1800
这里,我遵循的文档:http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-session.html
我也尝试过@rwinch定义的方法https://github.com/spring-projects/spring-session/issues/110但也没有成功.
更新......
我的配置文件请求:
#First attempt (server.session.timeout) following the Spring documentation mentioned
server:
session:
timeout: 10
spring:
#session timeout under spring (as mentioned by M Deinum in comment - unfortunately doesnt work)
session:
timeout: 10
redis:
host: 192.168.99.101
port: 6379
Run Code Online (Sandbox Code Playgroud)
除此之外,我还尝试实现一个负责设置超时的SessionListener(类似这样):
public class SessionListener implements HttpSessionListener {
@Value(value = "${server.session.timeout}")
private int timeout;
@Override
public void sessionCreated(HttpSessionEvent event) {
if(event!=null && event.getSession()!=null){
event.getSession().setMaxInactiveInterval(timeout); …Run Code Online (Sandbox Code Playgroud) 我正在尝试通过编写一个简单的 REST 应用程序来学习 Spring Boot,该应用程序将用户登录 ( POST /login) 并显示有关当前用户 ( GET /) 的信息。我正在使用 Redis 进行会话。
POST /login 按预期工作:它返回主体并在浏览器和 Redis 中设置会话 cookie。
GET /然而,随后的请求返回anonymousUser。我错过了什么?
pom.xml:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Run Code Online (Sandbox Code Playgroud)
application.properties:
spring.session.store-type=redis
server.servlet.session.timeout=3600s
spring.session.redis.flush-mode=on-save
spring.session.redis.namespace=spring:session
spring.redis.host=localhost
spring.redis.port=6379
Run Code Online (Sandbox Code Playgroud)
IndexController.java:
@Controller
public class IndexController {
private AuthenticationManager authenticationManager;
IndexController(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@GetMapping
ResponseEntity …Run Code Online (Sandbox Code Playgroud) 最近,我们开始使用spring redis会话作为会话管理器。在过去的8到10个月中,我们的应用已在生产中运行。有一个使用此后端的移动应用程序。
当我将会话存储库更改为春季会话时,移动应用程序中所有现有的已登录用户将自动注销。然后,他们将不得不再次登录。
无论如何,是否有将所有现有的已记录用户会话迁移到Redis实例的方法。
非常感谢您提前阅读这个问题.
我在用:
spring-security-oauth2:2.0.7.RELEASEspring-cloud-security:1.0.1.RELEASEspring-session:1.0.1.RELEASE并且在单一登录(),反向代理()网关中spring-security-oauth2 OAuth2ClientContext使用spring-session(via @EnableRedisHttpSession)时,会有一个关于Redis数据存储区中持久性的问题.@EnableOAuth2Sso@EnableZuulProxy
在我看来,创建的SessionScopedJdkDynamicAopProxied 未正确保存在Redis数据存储区中.DefaultOAuth2ClientContextorg.springframework.cloud.security.oauth2.client.OAuth2ClientAutoConfiguration
@Configuration
@ConditionalOnBean(OAuth2SsoConfiguration.class)
@ConditionalOnWebApplication
protected abstract static class SessionScopedConfiguration extends BaseConfiguration {
@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES)
public OAuth2ClientContext oauth2ClientContext() {
return new DefaultOAuth2ClientContext(accessTokenRequest);
}
}
Run Code Online (Sandbox Code Playgroud)
调试oauth2ClientContextwithout 的创建@EnableRedisHttpSession表明(如预期的那样)bean将在每个客户端会话中实例化一次并存储在HttpSession.然后,这个实例将被重用存储获取的OAuth2 bearerToken除了存储的OAuth2细节accessToken在春天SecurityContext的org.springframework.security.core.Authentication.
但是,一旦使用@EnableRedisHttpSession,oauth2ClientContextbean将首先在会话创建时创建,但也将在稍后创建(同时仍使用相同的客户端会话).调试Redis客户端会话内容可确认oauth2ClientContext会话创建未正确保留:
在我们检索OAuth2之前bearerToken(NO SpringContext,NO scopedTarget.oauth2ClientContext):
~$ …Run Code Online (Sandbox Code Playgroud) spring-security spring-security-oauth2 spring-session spring-cloud
我的问题是,在分布式Web应用程序中,可以使用Redis Store获取有效会话RedisOperationSessionRepository.(我的意思是我不想编写显式代码将其放入Redis存储区然后再读取它,我想了解框架或spring-data-redis库是否提供了这一点).
我知道Spring Redis能够恢复会话和服务器重启,如果会话仍然有效,也会保留登录(因为它由Redis支持)
我正在寻找的功能之一是获取当前在应用程序中的所有可能的登录用户.我知道SessionRegistryImpl,这个方法.但我注意到Redis不支持此方法,并且在服务器重新启动后,不会返回登录用户.
public List<Object> getAllPrincipals() {
return new ArrayList<Object>(principals.keySet());
}
Run Code Online (Sandbox Code Playgroud)
我可以尝试的功能之一是Spring Session 1.1.0,Spring会话用户名查找.
我试过,它确实返回了我有效的会话结果,但问题是我仍然需要知道使用此应用程序的所有当前有效用户名.(我不知道如何使用Redis Store获取它们,我再次可以存储在Redis中并获取它们,但我想知道是否有更好的方法).
这是一段代码,如果我知道会话ID,这是我可以从当前使用该系统的众多用户之一获得当前用户的方式.
final Session session = redisOperationsSessionRepository.getSession(sessionid);
final Object obj = session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
if (obj instanceof SecurityContext) {
final SecurityContext context = (SecurityContext) obj;
final Authentication authentication = context.getAuthentication();
if (authentication != null) {
final Object principal = authentication.getPrincipal();
if (principal != null && principal instanceof CurrentUser) {
return (CurrentUser) principal;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我可以使用上面的逻辑来获取所有当前用户,但是我应该再次使用所有有效的会话ID,我不知道如何从Redis商店获取.
新更新: …
spring-session ×10
spring-boot ×6
spring ×5
java ×3
redis ×3
spring-cloud ×1
spring-data ×1
spring-mvc ×1