Skip to content

Commit

Permalink
Added redis serialization for passkeys, upgread spring boot 3.4.0 - b…
Browse files Browse the repository at this point in the history
…uild authentication-service, build person-service, build kotlin-service, build user-service, build react-webapp, build go-service, build python-service
  • Loading branch information
rodrigorodrigues committed Nov 24, 2024
1 parent 2ac0826 commit 946b5fd
Show file tree
Hide file tree
Showing 243 changed files with 23,346 additions and 44,342 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ docker/jwks.json
access_token.json
docker/mongo_bkpk
*.log
php-service
Quick*.java
*.env
valid_token_google_oauth
*.java-version
quarkus-service/.java-version
quarkus-service/.java-version
input.json
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ Access it [Swagger UI](http://localhost:{SERVICE_PORT}/swagger-ui.html) - `http:
* [X] Java - Add JWKS Multiple Validation - Spring Boot 3
* [X] Java - Add Authorization Server - Spring Boot 3
* [X] Java - Removed Spring Oauth2 - Spring Boot 3
* [] BFF - Implement BFF Pattern

### References
[Pattern Microservice Architecture](https://microservices.io/patterns/microservices.html)
Expand Down
2 changes: 1 addition & 1 deletion admin-server/src/main/resources/logback-spring.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<!-- rollover daily and when the file reaches 10 MegaBytes -->
<fileNamePattern>${LOGGING_FILE}-%i-%d{yyyy-MM-dd}</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFileNamingAndTriggeringPolicy">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import java.util.stream.Collectors;

import com.microservice.authentication.common.model.Authentication;
import com.microservice.authentication.common.model.Authority;
import com.microservice.authentication.common.repository.AuthenticationCommonRepository;
import com.microservice.authentication.common.service.Base64DecodeUtil;
import com.microservice.authentication.common.service.SharedAuthenticationServiceImpl;
Expand All @@ -38,6 +37,7 @@
import org.springframework.core.io.Resource;
import org.springframework.data.mongodb.config.EnableMongoAuditing;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.encrypt.KeyStoreKeyFactory;
Expand All @@ -46,10 +46,9 @@
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;

@Slf4j
@Configuration
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(AuthenticationProperties.class)
@EnableMongoAuditing
@EnableMongoRepositories(basePackageClasses = AuthenticationCommonRepository.class)
Expand Down Expand Up @@ -102,7 +101,7 @@ public OAuth2TokenCustomizer<JwtEncodingContext> jwtTokenCustomizer() {
claims.put("fullName", auth.getFullName());
Set<String> roles = auth.getAuthorities()
.stream()
.map(Authority::getAuthority)
.map(GrantedAuthority::getAuthority)
.collect(Collectors.collectingAndThen(Collectors.toSet(), Collections::unmodifiableSet));
claims.put("authorities", roles);
} else if (context.getPrincipal() instanceof OidcUser oidcUser) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import lombok.NoArgsConstructor;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.security.core.userdetails.UserDetails;

Expand All @@ -26,6 +27,7 @@ public class Authentication implements UserDetails {
@Id
private String id;

@Indexed(unique = true)
private String email;

private String password;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<!-- rollover daily and when the file reaches 10 MegaBytes -->
<fileNamePattern>${LOGGING_FILE}-%i-%d{yyyy-MM-dd}</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFileNamingAndTriggeringPolicy">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
Expand Down
23 changes: 17 additions & 6 deletions authentication-service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,25 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<code-coverage>0.6</code-coverage>
<docker.image-tag>${project.version}</docker.image-tag>
<spring-security.version>6.4.0-SNAPSHOT</spring-security.version>
<!--<spring-security.version>6.4.0-SNAPSHOT</spring-security.version>-->
<wiremock-jre8-standalone.version>2.32.0</wiremock-jre8-standalone.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>

<dependency>
<groupId>com.webauthn4j</groupId>
<artifactId>webauthn4j-spring-security-core</artifactId>
<version>0.10.0.RELEASE</version>
<artifactId>webauthn4j-core</artifactId>
<version>0.28.2.RELEASE</version>
</dependency>
<!--
Expand Down Expand Up @@ -128,10 +133,10 @@
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>

<dependency>
<!--<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-rsa</artifactId>
</dependency>
</dependency>-->

<dependency>
<groupId>org.springframework.security</groupId>
Expand All @@ -155,6 +160,12 @@
<version>0.0.1-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>com.example</groupId>
<artifactId>redis-jackson-security-webauthn-otp</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
Expand Down Expand Up @@ -317,7 +328,7 @@
<id>native</id>
<properties>
<repackage.classifier>exec</repackage.classifier>
<native-buildtools.version>0.9.11</native-buildtools.version>
<native-buildtools.version>0.10.3</native-buildtools.version>
</properties>
<dependencies>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.microservice.authentication;

import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.interfaces.RSAPublicKey;
import java.util.Collections;
Expand All @@ -10,9 +9,6 @@
import java.util.UUID;
import java.util.concurrent.Executors;

import javax.crypto.spec.SecretKeySpec;

import com.microservice.authentication.autoconfigure.AuthenticationProperties;
import com.microservice.authentication.common.model.Authentication;
import com.microservice.authentication.common.model.Authority;
import com.microservice.authentication.common.repository.AuthenticationCommonRepository;
Expand All @@ -26,17 +22,13 @@
import com.nimbusds.jose.proc.SecurityContext;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.session.RedisSessionProperties;
import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.info.BuildProperties;
Expand All @@ -55,9 +47,7 @@
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtEncoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtEncoder;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
Expand All @@ -74,7 +64,7 @@
@EnableAsync
@Slf4j
@SpringBootApplication
@EnableConfigurationProperties({SpringSecurityConfiguration.RegistrationProperties.class, RedisSessionProperties.class})
@EnableConfigurationProperties({SpringSecurityConfiguration.RegistrationProperties.class, SpringSecurityConfiguration.WebAuthnProperties.class})
public class AuthenticationServiceApplication implements ApplicationContextAware {
private ApplicationContext applicationContext;

Expand Down Expand Up @@ -104,27 +94,7 @@ public PasswordEncoder encoder() {
}

@Bean
static BeanFactoryPostProcessor removeErrorSecurityFilter() {
return (beanFactory) -> {
try {
((DefaultListableBeanFactory) beanFactory).removeBeanDefinition("errorPageSecurityInterceptor");
} catch (Exception ignored) {}
};
}

/*@Bean
public JwtDecoder jwtDecoder(AuthenticationProperties properties) {
AuthenticationProperties.Jwt jwt = properties.getJwt();
if (jwt != null && StringUtils.isNotBlank(jwt.getKeyValue())) {
SecretKeySpec secretKeySpec = new SecretKeySpec(jwt.getKeyValue().getBytes(StandardCharsets.UTF_8), "HS256");
return NimbusJwtDecoder.withSecretKey(secretKeySpec).build();
} else {
RSAPublicKey publicKey = applicationContext.getBean(RSAPublicKey.class);
return NimbusJwtDecoder.withPublicKey(publicKey).build();
}
}*/

@Bean
@ConditionalOnMissingBean
JwtEncoder jwtEncoder() {
KeyPair keyPair = applicationContext.getBean(KeyPair.class);

Expand Down Expand Up @@ -206,40 +176,6 @@ GitProperties gitProperties() {
return new GitProperties(new Properties());
}

/*@ConditionalOnMissingBean
@Bean
Oauth2TokenStoreService redisTokenStoreService(DefaultTokenServices defaultTokenServices) {
return new Oauth2TokenStoreService() {
@Override
public OAuth2AccessToken generateToken(OAuth2Authentication oAuth2Authentication, boolean oauth2Login) {
if (oauth2Login) {
defaultTokenServices.setAccessTokenValiditySeconds(-1);
} else {
defaultTokenServices.setAccessTokenValiditySeconds(60 * 30);
}
log.debug("Creating new token for: {}", oAuth2Authentication.getName());
return defaultTokenServices.createAccessToken(oAuth2Authentication);
}
@Override
public void removeAllTokensByAuthenticationUser(org.springframework.security.core.Authentication authentication) {
}
@Override
public OAuth2AccessToken refreshToken(TokenRequest tokenRequest) {
return defaultTokenServices.refreshAccessToken(tokenRequest.getRequestParameters().get("refresh_token"), tokenRequest);
}
@Override
public OAuth2AccessToken getToken(org.springframework.security.core.Authentication authentication, boolean oauth2Login) {
OAuth2Request oAuth2Request = new OAuth2Request(null, authentication.getName(), authentication.getAuthorities(),
true, Collections.singleton("read"), null, null, null, null);
OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);
return generateToken(oAuth2Authentication, oauth2Login);
}
};
}*/

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
package com.microservice.authentication.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.microservice.authentication.service.CustomLogoutSuccessHandler;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.security.jackson2.SecurityJackson2Modules;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.session.FlushMode;
import org.springframework.session.SessionRepository;
Expand All @@ -24,18 +19,11 @@
@Configuration(proxyBeanMethods = false)
@EnableRedisHttpSession(flushMode = FlushMode.IMMEDIATE)
@Slf4j
public class RedisConfiguration implements BeanClassLoaderAware {
private ClassLoader loader;

public class RedisConfiguration {
public RedisConfiguration() {
log.info("RedisConfiguration:constructor");
}

@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer(objectMapper());
}

@ConditionalOnMissingBean
@Bean
public LettuceConnectionFactory redisConnectionFactory(RedisProperties redisProperties) {
Expand All @@ -47,22 +35,4 @@ public LettuceConnectionFactory redisConnectionFactory(RedisProperties redisProp
LogoutSuccessHandler customLogoutSuccessHandler(SessionRepository sessionRepository) {
return new CustomLogoutSuccessHandler(sessionRepository);
}

/**
* Customized {@link ObjectMapper} to add mix-in for class that doesn't have default
* constructors
*
* @return the {@link ObjectMapper} to use
*/
private ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModules(SecurityJackson2Modules.getModules(this.loader));
return mapper;
}

@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.loader = classLoader;
}

}
Loading

0 comments on commit 946b5fd

Please sign in to comment.