Skip to content

Commit 90a37fc

Browse files
author
Steve Riesenberg
committed
Federated Identity sample
Issue spring-projectsgh-538 Issue spring-projectsgh-499 Issue spring-projectsgh-106
1 parent a661e1c commit 90a37fc

24 files changed

+1228
-7
lines changed

samples/custom-consent-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public JWKSource<SecurityContext> jwkSource() {
103103

104104
@Bean
105105
public ProviderSettings providerSettings() {
106-
return ProviderSettings.builder().issuer("http://auth-server:9000").build();
106+
return ProviderSettings.builder().issuer("http://localhost:9000").build();
107107
}
108108

109109
@Bean

samples/custom-consent-authorizationserver/src/main/java/sample/config/DefaultSecurityConfig.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Excepti
3939
.authorizeRequests(authorizeRequests ->
4040
authorizeRequests.anyRequest().authenticated()
4141
)
42+
.cors(withDefaults())
4243
.formLogin(withDefaults());
4344
return http.build();
4445
}

samples/default-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,13 @@ public class AuthorizationServerConfig {
5959
@Order(Ordered.HIGHEST_PRECEDENCE)
6060
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
6161
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
62-
return http.formLogin(Customizer.withDefaults()).build();
62+
return http.cors(Customizer.withDefaults()).formLogin(Customizer.withDefaults()).build();
6363
}
6464

6565
// @formatter:off
6666
@Bean
6767
public RegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTemplate) {
68-
RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
68+
RegisteredClient confidentialClient = RegisteredClient.withId(UUID.randomUUID().toString())
6969
.clientId("messaging-client")
7070
.clientSecret("{noop}secret")
7171
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
@@ -79,10 +79,22 @@ public RegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTe
7979
.scope("message.write")
8080
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
8181
.build();
82+
RegisteredClient publicClient = RegisteredClient.withId(UUID.randomUUID().toString())
83+
.clientId("public-client")
84+
.clientAuthenticationMethod(ClientAuthenticationMethod.NONE)
85+
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
86+
.redirectUri("http://127.0.0.1:4200")
87+
.redirectUri("http://127.0.0.1:4200/silent-renew.html")
88+
.scope(OidcScopes.OPENID)
89+
.scope("message.read")
90+
.scope("message.write")
91+
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).requireProofKey(true).build())
92+
.build();
8293

8394
// Save registered client in db as if in-memory
8495
JdbcRegisteredClientRepository registeredClientRepository = new JdbcRegisteredClientRepository(jdbcTemplate);
85-
registeredClientRepository.save(registeredClient);
96+
registeredClientRepository.save(confidentialClient);
97+
registeredClientRepository.save(publicClient);
8698

8799
return registeredClientRepository;
88100
}
@@ -107,7 +119,7 @@ public JWKSource<SecurityContext> jwkSource() {
107119

108120
@Bean
109121
public ProviderSettings providerSettings() {
110-
return ProviderSettings.builder().issuer("http://auth-server:9000").build();
122+
return ProviderSettings.builder().issuer("http://localhost:9000").build();
111123
}
112124

113125
@Bean
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2020-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package sample.config;
17+
18+
import org.springframework.context.annotation.Bean;
19+
import org.springframework.context.annotation.Configuration;
20+
import org.springframework.web.cors.CorsConfiguration;
21+
import org.springframework.web.cors.CorsConfigurationSource;
22+
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
23+
24+
/**
25+
* @author Steve Riesenberg
26+
* @since 0.2.3
27+
*/
28+
@Configuration
29+
public class CorsConfig {
30+
31+
@Bean
32+
public CorsConfigurationSource corsConfigurationSource() {
33+
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
34+
CorsConfiguration config = new CorsConfiguration();
35+
config.addAllowedHeader("*");
36+
config.addAllowedMethod("*");
37+
config.addAllowedOrigin("http://127.0.0.1:4200");
38+
config.setAllowCredentials(true);
39+
source.registerCorsConfiguration("/**", config);
40+
return source;
41+
}
42+
43+
}

samples/default-authorizationserver/src/main/java/sample/config/DefaultSecurityConfig.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Excepti
4040
.authorizeRequests(authorizeRequests ->
4141
authorizeRequests.anyRequest().authenticated()
4242
)
43+
.cors(withDefaults())
4344
.formLogin(withDefaults());
4445
return http.build();
4546
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
apply plugin: 'io.spring.convention.spring-sample-boot'
2+
3+
dependencies {
4+
compile 'org.springframework.boot:spring-boot-starter-web'
5+
compile 'org.springframework.boot:spring-boot-starter-security'
6+
compile 'org.springframework.boot:spring-boot-starter-oauth2-client'
7+
compile 'org.springframework.boot:spring-boot-starter-thymeleaf'
8+
compile 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
9+
compile 'org.webjars:webjars-locator-core'
10+
compile 'org.webjars:bootstrap:3.4.1'
11+
compile 'org.webjars:jquery:3.4.1'
12+
compile 'org.springframework.boot:spring-boot-starter-jdbc'
13+
compile project(':spring-security-oauth2-authorization-server')
14+
runtimeOnly 'com.h2database:h2'
15+
16+
testCompile 'org.springframework.boot:spring-boot-starter-test'
17+
testCompile 'org.springframework.security:spring-security-test'
18+
testCompile 'net.sourceforge.htmlunit:htmlunit'
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2020-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package sample;
17+
18+
import org.springframework.boot.SpringApplication;
19+
import org.springframework.boot.autoconfigure.SpringBootApplication;
20+
21+
/**
22+
* @author Steve Riesenberg
23+
* @since 0.2.3
24+
*/
25+
@SpringBootApplication
26+
public class FederatedIdentityAuthorizationServerApplication {
27+
28+
public static void main(String[] args) {
29+
SpringApplication.run(FederatedIdentityAuthorizationServerApplication.class, args);
30+
}
31+
32+
}
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/*
2+
* Copyright 2020-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package sample.config;
17+
18+
import java.util.UUID;
19+
20+
import com.nimbusds.jose.jwk.JWKSet;
21+
import com.nimbusds.jose.jwk.RSAKey;
22+
import com.nimbusds.jose.jwk.source.JWKSource;
23+
import com.nimbusds.jose.proc.SecurityContext;
24+
import sample.jose.Jwks;
25+
import sample.security.FederatedIdentityConfigurer;
26+
27+
import org.springframework.context.annotation.Bean;
28+
import org.springframework.context.annotation.Configuration;
29+
import org.springframework.core.Ordered;
30+
import org.springframework.core.annotation.Order;
31+
import org.springframework.jdbc.core.JdbcTemplate;
32+
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
33+
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
34+
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
35+
import org.springframework.security.config.Customizer;
36+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
37+
import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
38+
import org.springframework.security.oauth2.core.AuthorizationGrantType;
39+
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
40+
import org.springframework.security.oauth2.core.oidc.OidcScopes;
41+
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationConsentService;
42+
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService;
43+
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService;
44+
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
45+
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository;
46+
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
47+
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
48+
import org.springframework.security.oauth2.server.authorization.config.ClientSettings;
49+
import org.springframework.security.oauth2.server.authorization.config.ProviderSettings;
50+
import org.springframework.security.web.SecurityFilterChain;
51+
52+
/**
53+
* @author Steve Riesenberg
54+
* @since 0.2.3
55+
*/
56+
@Configuration(proxyBeanMethods = false)
57+
public class AuthorizationServerConfig {
58+
59+
@Bean
60+
@Order(Ordered.HIGHEST_PRECEDENCE)
61+
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
62+
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
63+
http.apply(new FederatedIdentityConfigurer());
64+
return http.cors(Customizer.withDefaults()).formLogin(Customizer.withDefaults()).build();
65+
}
66+
67+
// @formatter:off
68+
@Bean
69+
public RegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTemplate) {
70+
RegisteredClient confidentialClient = RegisteredClient.withId(UUID.randomUUID().toString())
71+
.clientId("messaging-client")
72+
.clientSecret("{noop}secret")
73+
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
74+
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
75+
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
76+
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
77+
.redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc")
78+
.redirectUri("http://127.0.0.1:8080/authorized")
79+
.scope(OidcScopes.OPENID)
80+
.scope("message.read")
81+
.scope("message.write")
82+
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
83+
.build();
84+
RegisteredClient publicClient = RegisteredClient.withId(UUID.randomUUID().toString())
85+
.clientId("public-client")
86+
.clientAuthenticationMethod(ClientAuthenticationMethod.NONE)
87+
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
88+
.redirectUri("http://127.0.0.1:4200")
89+
.redirectUri("http://127.0.0.1:4200/silent-renew.html")
90+
.scope(OidcScopes.OPENID)
91+
.scope("message.read")
92+
.scope("message.write")
93+
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).requireProofKey(true).build())
94+
.build();
95+
96+
// Save registered client in db as if in-memory
97+
JdbcRegisteredClientRepository registeredClientRepository = new JdbcRegisteredClientRepository(jdbcTemplate);
98+
registeredClientRepository.save(confidentialClient);
99+
registeredClientRepository.save(publicClient);
100+
101+
return registeredClientRepository;
102+
}
103+
// @formatter:on
104+
105+
@Bean
106+
public OAuth2AuthorizationService authorizationService(JdbcTemplate jdbcTemplate, RegisteredClientRepository registeredClientRepository) {
107+
return new JdbcOAuth2AuthorizationService(jdbcTemplate, registeredClientRepository);
108+
}
109+
110+
@Bean
111+
public OAuth2AuthorizationConsentService authorizationConsentService(JdbcTemplate jdbcTemplate, RegisteredClientRepository registeredClientRepository) {
112+
return new JdbcOAuth2AuthorizationConsentService(jdbcTemplate, registeredClientRepository);
113+
}
114+
115+
@Bean
116+
public JWKSource<SecurityContext> jwkSource() {
117+
RSAKey rsaKey = Jwks.generateRsa();
118+
JWKSet jwkSet = new JWKSet(rsaKey);
119+
return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
120+
}
121+
122+
@Bean
123+
public ProviderSettings providerSettings() {
124+
return ProviderSettings.builder().issuer("http://localhost:9000").build();
125+
}
126+
127+
@Bean
128+
public EmbeddedDatabase embeddedDatabase() {
129+
// @formatter:off
130+
return new EmbeddedDatabaseBuilder()
131+
.generateUniqueName(true)
132+
.setType(EmbeddedDatabaseType.H2)
133+
.setScriptEncoding("UTF-8")
134+
.addScript("org/springframework/security/oauth2/server/authorization/oauth2-authorization-schema.sql")
135+
.addScript("org/springframework/security/oauth2/server/authorization/oauth2-authorization-consent-schema.sql")
136+
.addScript("org/springframework/security/oauth2/server/authorization/client/oauth2-registered-client-schema.sql")
137+
.build();
138+
// @formatter:on
139+
}
140+
141+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2020-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package sample.config;
17+
18+
import org.springframework.context.annotation.Bean;
19+
import org.springframework.context.annotation.Configuration;
20+
import org.springframework.web.cors.CorsConfiguration;
21+
import org.springframework.web.cors.CorsConfigurationSource;
22+
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
23+
24+
/**
25+
* @author Steve Riesenberg
26+
* @since 0.2.3
27+
*/
28+
@Configuration
29+
public class CorsConfig {
30+
31+
@Bean
32+
public CorsConfigurationSource corsConfigurationSource() {
33+
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
34+
CorsConfiguration config = new CorsConfiguration();
35+
config.addAllowedHeader("*");
36+
config.addAllowedMethod("*");
37+
config.addAllowedOrigin("http://127.0.0.1:4200");
38+
config.setAllowCredentials(true);
39+
source.registerCorsConfiguration("/**", config);
40+
return source;
41+
}
42+
43+
}

0 commit comments

Comments
 (0)