Skip to content

Commit b949500

Browse files
Merge pull request #2 from letsdev/1-add-spring-security-to-components
add ld sso integration to components
2 parents c1614a1 + b433ebd commit b949500

21 files changed

Lines changed: 1008 additions & 5 deletions

File tree

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package org.eclipse.digitaltwin.basyx.aasdiscoveryservice.feature.authorization.letsdev;
2+
3+
import org.springframework.boot.context.properties.ConfigurationProperties;
4+
import org.springframework.context.annotation.Configuration;
5+
6+
@Configuration
7+
@ConfigurationProperties("ld-sso")
8+
public class LdSsoConfigProperties {
9+
10+
String baseUrl;
11+
String audience;
12+
Boolean debugEnabled = false;
13+
String[] whitelistedIps = {};
14+
15+
public String[] getWhitelistedIps() {
16+
17+
return whitelistedIps;
18+
}
19+
20+
public String getBaseUrl() {
21+
22+
return baseUrl;
23+
}
24+
25+
public void setBaseUrl(String baseUrl) {
26+
27+
this.baseUrl = baseUrl;
28+
}
29+
30+
public String getAudience() {
31+
32+
return audience;
33+
}
34+
35+
public void setAudience(String audience) {
36+
37+
this.audience = audience;
38+
}
39+
40+
public Boolean getDebugEnabled() {
41+
42+
return debugEnabled;
43+
}
44+
45+
public void setDebugEnabled(Boolean debugEnabled) {
46+
47+
this.debugEnabled = debugEnabled;
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package org.eclipse.digitaltwin.basyx.aasdiscoveryservice.feature.authorization.letsdev;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
6+
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
7+
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
8+
import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator;
9+
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
10+
import org.springframework.security.oauth2.jwt.Jwt;
11+
import org.springframework.security.oauth2.jwt.JwtClaimValidator;
12+
import org.springframework.security.oauth2.jwt.JwtDecoder;
13+
import org.springframework.security.oauth2.jwt.JwtDecoders;
14+
import org.springframework.security.oauth2.jwt.JwtValidators;
15+
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
16+
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
17+
import org.springframework.security.web.SecurityFilterChain;
18+
import org.springframework.security.web.util.matcher.IpAddressMatcher;
19+
20+
import java.util.ArrayList;
21+
import java.util.List;
22+
import static org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames.AUD;
23+
24+
@Configuration
25+
@EnableWebSecurity(debug = true)
26+
public class WebSecurityConfig {
27+
28+
private static final String JWKS_PATH = "/.well-known/jwks.json";
29+
30+
private final LdSsoConfigProperties ldSsoConfigProperties;
31+
32+
public WebSecurityConfig(LdSsoConfigProperties ldSsoConfigProperties) {
33+
34+
this.ldSsoConfigProperties = ldSsoConfigProperties;
35+
}
36+
37+
@Bean
38+
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
39+
40+
http
41+
.oauth2ResourceServer(oauth2ResourceServerCustomizer ->
42+
oauth2ResourceServerCustomizer.jwt(jwtCustomizer -> {
43+
jwtCustomizer.jwkSetUri(ldSsoConfigProperties.getBaseUrl() + JWKS_PATH);
44+
jwtCustomizer.jwtAuthenticationConverter(new JwtAuthenticationConverter());
45+
jwtCustomizer.decoder(jwtDecoder()); // Validate jwt aud claim
46+
})
47+
)
48+
.authorizeHttpRequests(customizer -> {
49+
for (int i = 0; i < ldSsoConfigProperties.getWhitelistedIps().length; i++) {
50+
String currentIp = ldSsoConfigProperties.getWhitelistedIps()[i];
51+
customizer
52+
.requestMatchers(new IpAddressMatcher(currentIp))
53+
.permitAll();
54+
}
55+
56+
customizer
57+
.anyRequest()
58+
.authenticated();
59+
});
60+
61+
return http.build();
62+
}
63+
64+
OAuth2TokenValidator<Jwt> audienceValidator() {
65+
return new JwtClaimValidator<List<String>>(AUD, aud -> aud.contains(ldSsoConfigProperties.getAudience()));
66+
}
67+
68+
@Bean
69+
public JwtDecoder jwtDecoder() {
70+
71+
String issuerUri = ldSsoConfigProperties.getBaseUrl();
72+
73+
NimbusJwtDecoder jwtDecoder = JwtDecoders.fromIssuerLocation(issuerUri);
74+
75+
OAuth2TokenValidator<Jwt> audienceValidator = audienceValidator();
76+
OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(issuerUri);
77+
OAuth2TokenValidator<Jwt> withAudience = new DelegatingOAuth2TokenValidator<>(withIssuer, audienceValidator);
78+
79+
jwtDecoder.setJwtValidator(withAudience);
80+
81+
return jwtDecoder;
82+
}
83+
84+
@Bean
85+
public WebSecurityCustomizer webSecurityCustomizer() {
86+
87+
return web -> web.debug(ldSsoConfigProperties.getDebugEnabled());
88+
}
89+
}

basyx.aasdiscoveryservice/basyx.aasdiscoveryservice.component/src/main/resources/application.properties

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,9 @@ basyx.backend=InMemory
2828
#basyx.feature.authorization.type = rbac
2929
#basyx.feature.authorization.jwtBearerTokenProvider = keycloak
3030
#basyx.feature.authorization.rbac.file = classpath:rbac_rules.json
31-
#spring.security.oauth2.resourceserver.jwt.issuer-uri= http://localhost:9096/realms/BaSyx
31+
#spring.security.oauth2.resourceserver.jwt.issuer-uri= http://localhost:9096/realms/BaSyx
32+
33+
ld-sso.base-url = https://sso.twinmap.de
34+
ld-sso.audience = aas_twinmaps_daimler
35+
ld-sso.debug-enabled = false
36+
ld-sso.whitelisted-ips = TODO
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package org.eclipse.digitaltwin.basyx.aasenvironment.feature.authorization.letsdev;
2+
3+
import org.springframework.boot.context.properties.ConfigurationProperties;
4+
import org.springframework.context.annotation.Configuration;
5+
6+
@Configuration
7+
@ConfigurationProperties("ld-sso")
8+
public class LdSsoConfigProperties {
9+
10+
String baseUrl;
11+
String audience;
12+
Boolean debugEnabled = false;
13+
String[] whitelistedIps = {};
14+
15+
public String[] getWhitelistedIps() {
16+
17+
return whitelistedIps;
18+
}
19+
20+
public String getBaseUrl() {
21+
22+
return baseUrl;
23+
}
24+
25+
public void setBaseUrl(String baseUrl) {
26+
27+
this.baseUrl = baseUrl;
28+
}
29+
30+
public String getAudience() {
31+
32+
return audience;
33+
}
34+
35+
public void setAudience(String audience) {
36+
37+
this.audience = audience;
38+
}
39+
40+
public Boolean getDebugEnabled() {
41+
42+
return debugEnabled;
43+
}
44+
45+
public void setDebugEnabled(Boolean debugEnabled) {
46+
47+
this.debugEnabled = debugEnabled;
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package org.eclipse.digitaltwin.basyx.aasenvironment.feature.authorization.letsdev;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
6+
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
7+
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
8+
import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator;
9+
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
10+
import org.springframework.security.oauth2.jwt.Jwt;
11+
import org.springframework.security.oauth2.jwt.JwtClaimValidator;
12+
import org.springframework.security.oauth2.jwt.JwtDecoder;
13+
import org.springframework.security.oauth2.jwt.JwtDecoders;
14+
import org.springframework.security.oauth2.jwt.JwtValidators;
15+
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
16+
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
17+
import org.springframework.security.web.SecurityFilterChain;
18+
import org.springframework.security.web.util.matcher.IpAddressMatcher;
19+
20+
import java.util.List;
21+
22+
import static org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames.AUD;
23+
24+
@Configuration
25+
@EnableWebSecurity(debug = true)
26+
public class WebSecurityConfig {
27+
28+
private static final String JWKS_PATH = "/.well-known/jwks.json";
29+
30+
private final LdSsoConfigProperties ldSsoConfigProperties;
31+
32+
public WebSecurityConfig(LdSsoConfigProperties ldSsoConfigProperties) {
33+
34+
this.ldSsoConfigProperties = ldSsoConfigProperties;
35+
}
36+
37+
@Bean
38+
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
39+
40+
http
41+
.oauth2ResourceServer(oauth2ResourceServerCustomizer ->
42+
oauth2ResourceServerCustomizer.jwt(jwtCustomizer -> {
43+
jwtCustomizer.jwkSetUri(ldSsoConfigProperties.getBaseUrl() + JWKS_PATH);
44+
jwtCustomizer.jwtAuthenticationConverter(new JwtAuthenticationConverter());
45+
jwtCustomizer.decoder(jwtDecoder()); // Validate jwt aud claim
46+
})
47+
)
48+
.authorizeHttpRequests(customizer -> {
49+
for (int i = 0; i < ldSsoConfigProperties.getWhitelistedIps().length; i++) {
50+
String currentIp = ldSsoConfigProperties.getWhitelistedIps()[i];
51+
customizer
52+
.requestMatchers(new IpAddressMatcher(currentIp))
53+
.permitAll();
54+
}
55+
56+
customizer
57+
.anyRequest()
58+
.authenticated();
59+
});
60+
61+
return http.build();
62+
}
63+
64+
OAuth2TokenValidator<Jwt> audienceValidator() {
65+
return new JwtClaimValidator<List<String>>(AUD, aud -> aud.contains(ldSsoConfigProperties.getAudience()));
66+
}
67+
68+
@Bean
69+
public JwtDecoder jwtDecoder() {
70+
71+
String issuerUri = ldSsoConfigProperties.getBaseUrl();
72+
73+
NimbusJwtDecoder jwtDecoder = JwtDecoders.fromIssuerLocation(issuerUri);
74+
75+
OAuth2TokenValidator<Jwt> audienceValidator = audienceValidator();
76+
OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(issuerUri);
77+
OAuth2TokenValidator<Jwt> withAudience = new DelegatingOAuth2TokenValidator<>(withIssuer, audienceValidator);
78+
79+
jwtDecoder.setJwtValidator(withAudience);
80+
81+
return jwtDecoder;
82+
}
83+
84+
@Bean
85+
public WebSecurityCustomizer webSecurityCustomizer() {
86+
87+
return web -> web.debug(ldSsoConfigProperties.getDebugEnabled());
88+
}
89+
}

basyx.aasenvironment/basyx.aasenvironment.component/src/main/resources/application.properties

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,9 @@ basyx.backend = InMemory
7373
####################################################################################
7474
# To define the total request size for a multipart/form-data (default 10 MB)
7575

76-
# spring.servlet.multipart.max-request-size=128KB
76+
# spring.servlet.multipart.max-request-size=128KB
77+
78+
ld-sso.base-url = https://sso.twinmap.de
79+
ld-sso.audience = aas_twinmaps_daimler
80+
ld-sso.debug-enabled = false
81+
ld-sso.whitelisted-ips = TODO
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package org.eclipse.digitaltwin.basyx.aasregistry.feature.authorization.letsdev;
2+
3+
import org.springframework.boot.context.properties.ConfigurationProperties;
4+
import org.springframework.context.annotation.Configuration;
5+
6+
@Configuration
7+
@ConfigurationProperties("ld-sso")
8+
public class LdSsoConfigProperties {
9+
10+
String baseUrl;
11+
String audience;
12+
Boolean debugEnabled = false;
13+
String[] whitelistedIps = {};
14+
15+
public String[] getWhitelistedIps() {
16+
17+
return whitelistedIps;
18+
}
19+
20+
public String getBaseUrl() {
21+
22+
return baseUrl;
23+
}
24+
25+
public void setBaseUrl(String baseUrl) {
26+
27+
this.baseUrl = baseUrl;
28+
}
29+
30+
public String getAudience() {
31+
32+
return audience;
33+
}
34+
35+
public void setAudience(String audience) {
36+
37+
this.audience = audience;
38+
}
39+
40+
public Boolean getDebugEnabled() {
41+
42+
return debugEnabled;
43+
}
44+
45+
public void setDebugEnabled(Boolean debugEnabled) {
46+
47+
this.debugEnabled = debugEnabled;
48+
}
49+
}

0 commit comments

Comments
 (0)