我怎样才能在 spring 启动应用程序中获得具有 spring 安全性和 Redis 的当前经过身份验证的用户主体
How can i get currently authenticated user Principal with spring security and Redis in spring boot application
我想使用 spring 安全性和 Json Web 令牌 (JWT) 来保护我的服务,并在用户发送时使用 spring session.So 将登录的用户存储在 redis 中登录请求我对用户进行身份验证,然后将生成的令牌发回,如下所示:
public ResponseEntity<?> createAuthenticationToken(@RequestBody JwtAuthenticationRequest authenticationRequest, Device device) throws AuthenticationException {
// Perform the security
final Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
authenticationRequest.getUsername(),
authenticationRequest.getPassword()
)
);
SecurityContextHolder.getContext().setAuthentication(authentication);
final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());
final String token = jwtTokenUtil.generateToken(userDetails, device);
// Return the token
return ResponseEntity.ok(new JwtAuthenticationResponse(token));
}
而且我将该用户添加到会话(支持的 Redis 会话):
HttpSession session = request.getSession(false);
if (session != null) {
session.setMaxInactiveInterval(30 * 600);
JwtUser user = (JwtUser) authentication.getPrincipal();
session.setAttribute("user", user);
}
在我检查 redis 之后,我看到用户会话已经设置为 redis.But 当我收到用户的下一次尝试时它变成了 anonymousUser ,理想情况下它应该't.Reason这个问题背后是传入的JSESSIONID不知何故无效。
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
我看到 debug screen 委托人 returns anonymousUser。
我也尝试如下:
@RequestMapping(value = "/username", method = RequestMethod.GET)
@ResponseBody
public String currentUserNameSimple(HttpServletRequest request) {
Principal principal = request.getUserPrincipal();
return principal.getName();
}
但是本金为空。
我的redis配置:
@Configuration
@EnableRedisHttpSession
public class RedisConfig implements BeanClassLoaderAware {
private ClassLoader loader;
@Bean(name = { "defaultRedisSerializer", "springSessionDefaultRedisSerializer" })
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer(objectMapper());
}
@Bean
public HttpSessionStrategy httpSessionStrategy() {
return new HeaderHttpSessionStrategy();
}
@Bean
JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory jedisConFactory = new JedisConnectionFactory();
jedisConFactory.setHostName("localhost");
jedisConFactory.setPort(6379);
return jedisConFactory;
}
ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModules(SecurityJackson2Modules.getModules(this.loader));
return mapper;
}
public void setBeanClassLoader(ClassLoader classLoader) {
this.loader = classLoader;
}
}
Maven 依赖项:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>1.4.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<!-- Password Validation -->
<dependency>
<groupId>org.passay</groupId>
<artifactId>passay</artifactId>
<version>${passay.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.mobile</groupId>
<artifactId>spring-mobile-device</artifactId>
<version>1.1.4.RELEASE</version>
</dependency>
<!--JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
<dependency>
<groupId>az.com.cybernet.utilities</groupId>
<artifactId>utilities</artifactId>
<version>0.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>az.com.cybernet.beans</groupId>
<artifactId>disieibeans</artifactId>
<version>0.0.1</version>
<scope>compile</scope>
</dependency>
<!-- DB dependencies -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4-1200-jdbc41</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>4.8</version>
</dependency>
<!-- REDIS -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
</dependencies>
没有 Redis 一切都很好,但是使用 redis 我无法获得当前经过身份验证的用户的主体
Similar Question Asked Here.
使用 auth-key/sessionId 调用 redisOperationsSessionRepository。
希望对您有所帮助:)
我刚刚将 jedis 客户端更改为如下所示的 lettuce 客户端,它解决了问题:
<dependency>
<groupId>biz.paluch.redis</groupId>
<artifactId>lettuce</artifactId>
<version>3.5.0.Final</version>
</dependency>
之前 spring security Principal 对象为空,因为名为 "JSESSIONID" 的 cookie 尚未由 Jedis 客户端创建。
@EnableRedisHttpSession
public class RedisConfig {
@Bean
public LettuceConnectionFactory connectionFactory() {
return new LettuceConnectionFactory();
}
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setCookieName("JSESSIONID"); // <1>
serializer.setCookiePath("/"); // <2>
serializer.setDomainNamePattern("^.+?\.(\w+\.[a-z]+)$"); // <3>
return serializer;
}
}
我想使用 spring 安全性和 Json Web 令牌 (JWT) 来保护我的服务,并在用户发送时使用 spring session.So 将登录的用户存储在 redis 中登录请求我对用户进行身份验证,然后将生成的令牌发回,如下所示:
public ResponseEntity<?> createAuthenticationToken(@RequestBody JwtAuthenticationRequest authenticationRequest, Device device) throws AuthenticationException {
// Perform the security
final Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
authenticationRequest.getUsername(),
authenticationRequest.getPassword()
)
);
SecurityContextHolder.getContext().setAuthentication(authentication);
final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());
final String token = jwtTokenUtil.generateToken(userDetails, device);
// Return the token
return ResponseEntity.ok(new JwtAuthenticationResponse(token));
}
而且我将该用户添加到会话(支持的 Redis 会话):
HttpSession session = request.getSession(false);
if (session != null) {
session.setMaxInactiveInterval(30 * 600);
JwtUser user = (JwtUser) authentication.getPrincipal();
session.setAttribute("user", user);
}
在我检查 redis 之后,我看到用户会话已经设置为 redis.But 当我收到用户的下一次尝试时它变成了 anonymousUser ,理想情况下它应该't.Reason这个问题背后是传入的JSESSIONID不知何故无效。
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
我看到 debug screen 委托人 returns anonymousUser。
我也尝试如下:
@RequestMapping(value = "/username", method = RequestMethod.GET)
@ResponseBody
public String currentUserNameSimple(HttpServletRequest request) {
Principal principal = request.getUserPrincipal();
return principal.getName();
}
但是本金为空。
我的redis配置:
@Configuration
@EnableRedisHttpSession
public class RedisConfig implements BeanClassLoaderAware {
private ClassLoader loader;
@Bean(name = { "defaultRedisSerializer", "springSessionDefaultRedisSerializer" })
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer(objectMapper());
}
@Bean
public HttpSessionStrategy httpSessionStrategy() {
return new HeaderHttpSessionStrategy();
}
@Bean
JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory jedisConFactory = new JedisConnectionFactory();
jedisConFactory.setHostName("localhost");
jedisConFactory.setPort(6379);
return jedisConFactory;
}
ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModules(SecurityJackson2Modules.getModules(this.loader));
return mapper;
}
public void setBeanClassLoader(ClassLoader classLoader) {
this.loader = classLoader;
}
}
Maven 依赖项:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>1.4.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<!-- Password Validation -->
<dependency>
<groupId>org.passay</groupId>
<artifactId>passay</artifactId>
<version>${passay.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.mobile</groupId>
<artifactId>spring-mobile-device</artifactId>
<version>1.1.4.RELEASE</version>
</dependency>
<!--JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
<dependency>
<groupId>az.com.cybernet.utilities</groupId>
<artifactId>utilities</artifactId>
<version>0.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>az.com.cybernet.beans</groupId>
<artifactId>disieibeans</artifactId>
<version>0.0.1</version>
<scope>compile</scope>
</dependency>
<!-- DB dependencies -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4-1200-jdbc41</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>4.8</version>
</dependency>
<!-- REDIS -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
</dependencies>
没有 Redis 一切都很好,但是使用 redis 我无法获得当前经过身份验证的用户的主体
Similar Question Asked Here.
使用 auth-key/sessionId 调用 redisOperationsSessionRepository。
希望对您有所帮助:)
我刚刚将 jedis 客户端更改为如下所示的 lettuce 客户端,它解决了问题:
<dependency>
<groupId>biz.paluch.redis</groupId>
<artifactId>lettuce</artifactId>
<version>3.5.0.Final</version>
</dependency>
之前 spring security Principal 对象为空,因为名为 "JSESSIONID" 的 cookie 尚未由 Jedis 客户端创建。
@EnableRedisHttpSession
public class RedisConfig {
@Bean
public LettuceConnectionFactory connectionFactory() {
return new LettuceConnectionFactory();
}
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setCookieName("JSESSIONID"); // <1>
serializer.setCookiePath("/"); // <2>
serializer.setDomainNamePattern("^.+?\.(\w+\.[a-z]+)$"); // <3>
return serializer;
}
}