Skip to content

Commit 95ab08c

Browse files
committed
[BAEL-9245] Added classes needed to implement core services with redis
One of the things noticed is that we need to use RegisteredClients instead of the client set in the properties file.
1 parent 0e21455 commit 95ab08c

28 files changed

+1604
-18
lines changed

oauth-authorization-server-with-redis/redis-authorization-server/pom.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@
2626
<groupId>org.springframework.boot</groupId>
2727
<artifactId>spring-boot-starter-oauth2-authorization-server</artifactId>
2828
</dependency>
29+
<dependency>
30+
<groupId>org.springframework.boot</groupId>
31+
<artifactId>spring-boot-starter-data-redis</artifactId>
32+
</dependency>
33+
34+
<dependency>
35+
<groupId>com.github.codemonstur</groupId>
36+
<artifactId>embedded-redis</artifactId>
37+
<version>1.4.2</version>
38+
</dependency>
2939

3040
<dependency>
3141
<groupId>org.springframework.boot</groupId>

oauth-authorization-server-with-redis/redis-authorization-server/src/main/java/com/baeldung/OAuth2AuthorizationServerApplication.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,4 @@ public class OAuth2AuthorizationServerApplication {
99
public static void main(String[] args) {
1010
SpringApplication.run(OAuth2AuthorizationServerApplication.class, args);
1111
}
12-
1312
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package com.baeldung.config;
2+
3+
import java.io.IOException;
4+
import java.util.Arrays;
5+
6+
import org.springframework.beans.factory.annotation.Value;
7+
import org.springframework.context.annotation.Bean;
8+
import org.springframework.context.annotation.Configuration;
9+
import org.springframework.core.annotation.Order;
10+
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
11+
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
12+
import org.springframework.data.redis.core.RedisTemplate;
13+
import org.springframework.data.redis.core.convert.RedisCustomConversions;
14+
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
15+
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
16+
17+
import com.baeldung.convert.BytesToClaimsHolderConverter;
18+
import com.baeldung.convert.BytesToOAuth2AuthorizationRequestConverter;
19+
import com.baeldung.convert.BytesToUsernamePasswordAuthenticationTokenConverter;
20+
import com.baeldung.convert.ClaimsHolderToBytesConverter;
21+
import com.baeldung.convert.OAuth2AuthorizationRequestToBytesConverter;
22+
import com.baeldung.convert.UsernamePasswordAuthenticationTokenToBytesConverter;
23+
import com.baeldung.repository.OAuth2AuthorizationGrantAuthorizationRepository;
24+
import com.baeldung.repository.OAuth2RegisteredClientRepository;
25+
import com.baeldung.repository.OAuth2UserConsentRepository;
26+
import com.baeldung.service.RedisOAuth2AuthorizationConsentService;
27+
import com.baeldung.service.RedisOAuth2AuthorizationService;
28+
import com.baeldung.service.RedisRegisteredClientRepository;
29+
30+
import jakarta.annotation.PostConstruct;
31+
import jakarta.annotation.PreDestroy;
32+
import redis.embedded.RedisServer;
33+
34+
@Configuration(proxyBeanMethods = false)
35+
@EnableRedisRepositories
36+
public class RedisConfig {
37+
38+
private final String redisHost;
39+
private final int redisPort;
40+
private final RedisServer redisServer;
41+
42+
public RedisConfig(@Value("${spring.data.redis.host}") String redisHost, @Value("${spring.data.redis.port}") int redisPort) throws IOException {
43+
this.redisHost = redisHost;
44+
this.redisPort = redisPort;
45+
this.redisServer = new RedisServer(redisPort);
46+
}
47+
48+
@PostConstruct
49+
public void postConstruct() throws IOException {
50+
redisServer.start();
51+
}
52+
53+
@PreDestroy
54+
public void preDestroy() throws IOException {
55+
redisServer.stop();
56+
}
57+
58+
@Bean
59+
@Order(1)
60+
public JedisConnectionFactory redisConnectionFactory() {
61+
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(redisHost, redisPort);
62+
63+
return new JedisConnectionFactory(redisStandaloneConfiguration);
64+
}
65+
66+
@Bean
67+
@Order(2)
68+
public RedisTemplate<?, ?> redisTemplate(JedisConnectionFactory connectionFactory) {
69+
RedisTemplate<byte[], byte[]> template = new RedisTemplate<>();
70+
template.setConnectionFactory(connectionFactory);
71+
return template;
72+
}
73+
74+
@Bean
75+
@Order(3)
76+
public RedisCustomConversions redisCustomConversions() {
77+
return new RedisCustomConversions(
78+
Arrays.asList(new UsernamePasswordAuthenticationTokenToBytesConverter(), new BytesToUsernamePasswordAuthenticationTokenConverter(),
79+
new OAuth2AuthorizationRequestToBytesConverter(), new BytesToOAuth2AuthorizationRequestConverter(), new ClaimsHolderToBytesConverter(),
80+
new BytesToClaimsHolderConverter()));
81+
}
82+
83+
@Bean
84+
@Order(4)
85+
public RedisRegisteredClientRepository registeredClientRepository(OAuth2RegisteredClientRepository registeredClientRepository) {
86+
RedisRegisteredClientRepository redisRegisteredClientRepository = new RedisRegisteredClientRepository(registeredClientRepository);
87+
redisRegisteredClientRepository.save(RegisteredClients.messagingClient());
88+
89+
return redisRegisteredClientRepository;
90+
}
91+
92+
@Bean
93+
@Order(5)
94+
public RedisOAuth2AuthorizationService authorizationService(RegisteredClientRepository registeredClientRepository,
95+
OAuth2AuthorizationGrantAuthorizationRepository authorizationGrantAuthorizationRepository) {
96+
return new RedisOAuth2AuthorizationService(registeredClientRepository, authorizationGrantAuthorizationRepository);
97+
}
98+
99+
@Bean
100+
@Order(6)
101+
public RedisOAuth2AuthorizationConsentService authorizationConsentService(OAuth2UserConsentRepository userConsentRepository) {
102+
return new RedisOAuth2AuthorizationConsentService(userConsentRepository);
103+
}
104+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.baeldung.config;
2+
3+
import java.util.UUID;
4+
5+
import org.springframework.security.oauth2.core.AuthorizationGrantType;
6+
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
7+
import org.springframework.security.oauth2.core.oidc.OidcScopes;
8+
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
9+
10+
public class RegisteredClients {
11+
12+
public static RegisteredClient messagingClient() {
13+
return RegisteredClient.withId(UUID.randomUUID()
14+
.toString())
15+
.clientId("articles-client")
16+
.clientSecret("{noop}secret")
17+
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
18+
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
19+
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
20+
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
21+
.authorizationGrantType(AuthorizationGrantType.DEVICE_CODE)
22+
.redirectUri("http://127.0.0.1:8080/login/oauth2/code/articles-client-oidc")
23+
.redirectUri("http://127.0.0.1:8080/authorized")
24+
.postLogoutRedirectUri("http://127.0.0.1:9000/login")
25+
.scope(OidcScopes.OPENID)
26+
.scope("articles.read")
27+
.build();
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.baeldung.convert;
2+
3+
import org.springframework.core.convert.converter.Converter;
4+
import org.springframework.data.convert.ReadingConverter;
5+
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
6+
import org.springframework.security.jackson2.SecurityJackson2Modules;
7+
import org.springframework.security.oauth2.server.authorization.jackson2.OAuth2AuthorizationServerJackson2Module;
8+
9+
import com.baeldung.entity.OAuth2AuthorizationGrantAuthorization;
10+
import com.fasterxml.jackson.databind.ObjectMapper;
11+
12+
@ReadingConverter
13+
public class BytesToClaimsHolderConverter implements Converter<byte[], OAuth2AuthorizationGrantAuthorization.ClaimsHolder> {
14+
15+
private final Jackson2JsonRedisSerializer<OAuth2AuthorizationGrantAuthorization.ClaimsHolder> serializer;
16+
17+
public BytesToClaimsHolderConverter() {
18+
ObjectMapper objectMapper = new ObjectMapper();
19+
objectMapper.registerModules(SecurityJackson2Modules.getModules(BytesToClaimsHolderConverter.class.getClassLoader()));
20+
objectMapper.registerModule(new OAuth2AuthorizationServerJackson2Module());
21+
objectMapper.addMixIn(OAuth2AuthorizationGrantAuthorization.ClaimsHolder.class, ClaimsHolderMixin.class);
22+
this.serializer = new Jackson2JsonRedisSerializer<>(objectMapper, OAuth2AuthorizationGrantAuthorization.ClaimsHolder.class);
23+
}
24+
25+
@Override
26+
public OAuth2AuthorizationGrantAuthorization.ClaimsHolder convert(byte[] value) {
27+
return this.serializer.deserialize(value);
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.baeldung.convert;
2+
3+
import org.springframework.core.convert.converter.Converter;
4+
import org.springframework.data.convert.ReadingConverter;
5+
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
6+
import org.springframework.security.jackson2.SecurityJackson2Modules;
7+
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
8+
import org.springframework.security.oauth2.server.authorization.jackson2.OAuth2AuthorizationServerJackson2Module;
9+
10+
import com.fasterxml.jackson.databind.ObjectMapper;
11+
12+
@ReadingConverter
13+
public class BytesToOAuth2AuthorizationRequestConverter implements Converter<byte[], OAuth2AuthorizationRequest> {
14+
15+
private final Jackson2JsonRedisSerializer<OAuth2AuthorizationRequest> serializer;
16+
17+
public BytesToOAuth2AuthorizationRequestConverter() {
18+
ObjectMapper objectMapper = new ObjectMapper();
19+
objectMapper.registerModules(SecurityJackson2Modules.getModules(BytesToOAuth2AuthorizationRequestConverter.class.getClassLoader()));
20+
objectMapper.registerModule(new OAuth2AuthorizationServerJackson2Module());
21+
this.serializer = new Jackson2JsonRedisSerializer<>(objectMapper, OAuth2AuthorizationRequest.class);
22+
}
23+
24+
@Override
25+
public OAuth2AuthorizationRequest convert(byte[] value) {
26+
return this.serializer.deserialize(value);
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.baeldung.convert;
2+
3+
import org.springframework.core.convert.converter.Converter;
4+
import org.springframework.data.convert.ReadingConverter;
5+
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
6+
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
7+
import org.springframework.security.jackson2.SecurityJackson2Modules;
8+
9+
import com.fasterxml.jackson.databind.ObjectMapper;
10+
11+
@ReadingConverter
12+
public class BytesToUsernamePasswordAuthenticationTokenConverter implements Converter<byte[], UsernamePasswordAuthenticationToken> {
13+
14+
private final Jackson2JsonRedisSerializer<UsernamePasswordAuthenticationToken> serializer;
15+
16+
public BytesToUsernamePasswordAuthenticationTokenConverter() {
17+
ObjectMapper objectMapper = new ObjectMapper();
18+
objectMapper.registerModules(SecurityJackson2Modules.getModules(BytesToUsernamePasswordAuthenticationTokenConverter.class.getClassLoader()));
19+
this.serializer = new Jackson2JsonRedisSerializer<>(objectMapper, UsernamePasswordAuthenticationToken.class);
20+
}
21+
22+
@Override
23+
public UsernamePasswordAuthenticationToken convert(byte[] value) {
24+
return this.serializer.deserialize(value);
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.baeldung.convert;
2+
3+
import java.util.Map;
4+
5+
import com.fasterxml.jackson.annotation.JsonAutoDetect;
6+
import com.fasterxml.jackson.annotation.JsonCreator;
7+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
8+
import com.fasterxml.jackson.annotation.JsonProperty;
9+
import com.fasterxml.jackson.annotation.JsonTypeInfo;
10+
11+
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
12+
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE, isGetterVisibility = JsonAutoDetect.Visibility.NONE, creatorVisibility = JsonAutoDetect.Visibility.NONE)
13+
@JsonIgnoreProperties(ignoreUnknown = true)
14+
abstract class ClaimsHolderMixin {
15+
16+
@JsonCreator
17+
ClaimsHolderMixin(@JsonProperty("claims") Map<String, Object> claims) {
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.baeldung.convert;
2+
3+
import org.springframework.core.convert.converter.Converter;
4+
import org.springframework.data.convert.WritingConverter;
5+
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
6+
import org.springframework.security.jackson2.SecurityJackson2Modules;
7+
import org.springframework.security.oauth2.server.authorization.jackson2.OAuth2AuthorizationServerJackson2Module;
8+
9+
import com.baeldung.entity.OAuth2AuthorizationGrantAuthorization;
10+
import com.fasterxml.jackson.databind.ObjectMapper;
11+
12+
@WritingConverter
13+
public class ClaimsHolderToBytesConverter implements Converter<OAuth2AuthorizationGrantAuthorization.ClaimsHolder, byte[]> {
14+
15+
private final Jackson2JsonRedisSerializer<OAuth2AuthorizationGrantAuthorization.ClaimsHolder> serializer;
16+
17+
public ClaimsHolderToBytesConverter() {
18+
ObjectMapper objectMapper = new ObjectMapper();
19+
objectMapper.registerModules(SecurityJackson2Modules.getModules(ClaimsHolderToBytesConverter.class.getClassLoader()));
20+
objectMapper.registerModules(new OAuth2AuthorizationServerJackson2Module());
21+
objectMapper.addMixIn(OAuth2AuthorizationGrantAuthorization.ClaimsHolder.class, ClaimsHolderMixin.class);
22+
this.serializer = new Jackson2JsonRedisSerializer<>(objectMapper, OAuth2AuthorizationGrantAuthorization.ClaimsHolder.class);
23+
}
24+
25+
@Override
26+
public byte[] convert(OAuth2AuthorizationGrantAuthorization.ClaimsHolder value) {
27+
return this.serializer.serialize(value);
28+
}
29+
}

0 commit comments

Comments
 (0)