Skip to content

Commit 2814bc3

Browse files
author
Steve Riesenberg
committed
Refresh Getting Started example
Closes gh-1186
1 parent 697d6e9 commit 2814bc3

File tree

5 files changed

+81
-68
lines changed

5 files changed

+81
-68
lines changed

docs/src/docs/asciidoc/examples/src/main/java/sample/gettingStarted/SecurityConfig.java

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
import org.springframework.core.annotation.Order;
3333
import org.springframework.security.config.Customizer;
3434
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
35-
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
35+
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
3636
import org.springframework.security.core.userdetails.User;
3737
import org.springframework.security.core.userdetails.UserDetails;
3838
import org.springframework.security.core.userdetails.UserDetailsService;
@@ -52,6 +52,7 @@
5252
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
5353

5454
@Configuration
55+
@EnableWebSecurity
5556
public class SecurityConfig {
5657

5758
@Bean // <1>
@@ -70,7 +71,7 @@ public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity h
7071
new LoginUrlAuthenticationEntryPoint("/login"))
7172
)
7273
// Accept access tokens for User Info and/or Client Registration
73-
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
74+
.oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults()));
7475
// @formatter:on
7576

7677
return http.build();
@@ -109,26 +110,21 @@ public UserDetailsService userDetailsService() {
109110
@Bean // <4>
110111
public RegisteredClientRepository registeredClientRepository() {
111112
// @formatter:off
112-
RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
113-
.clientId("messaging-client")
113+
RegisteredClient oidcClient = RegisteredClient.withId(UUID.randomUUID().toString())
114+
.clientId("oidc-client")
114115
.clientSecret("{noop}secret")
115116
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
116117
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
117118
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
118-
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
119-
.authorizationGrantType(AuthorizationGrantType.DEVICE_CODE)
120-
.redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc")
121-
.redirectUri("http://127.0.0.1:8080/authorized")
122-
.postLogoutRedirectUri("http://127.0.0.1:8080/index")
119+
.redirectUri("http://127.0.0.1:8080/login/oauth2/code/oidc-client")
120+
.postLogoutRedirectUri("http://127.0.0.1:8080/")
123121
.scope(OidcScopes.OPENID)
124122
.scope(OidcScopes.PROFILE)
125-
.scope("message.read")
126-
.scope("message.write")
127123
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
128124
.build();
129125
// @formatter:on
130126

131-
return new InMemoryRegisteredClientRepository(registeredClient);
127+
return new InMemoryRegisteredClientRepository(oidcClient);
132128
}
133129

134130
@Bean // <5>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
server:
2+
port: 9000
3+
4+
logging:
5+
level:
6+
org.springframework.security: trace
7+
8+
spring:
9+
security:
10+
oauth2:
11+
authorizationserver:
12+
client:
13+
oidc-client:
14+
registration:
15+
client-id: "oidc-client"
16+
client-secret: "{noop}secret"
17+
client-authentication-methods:
18+
- "client_secret_basic"
19+
authorization-grant-types:
20+
- "authorization_code"
21+
- "refresh_token"
22+
redirect-uris:
23+
- "http://127.0.0.1:8080/login/oauth2/code/oidc-client"
24+
post-logout-redirect-uris:
25+
- "http://127.0.0.1:8080/"
26+
scopes:
27+
- "openid"
28+
- "profile"
29+
require-authorization-consent: true

docs/src/docs/asciidoc/examples/src/test/java/sample/AuthorizationCodeGrantFlow.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ public String submitConsent(RegisteredClient registeredClient, String state) thr
127127
.andReturn();
128128
String redirectedUrl = mvcResult.getResponse().getRedirectedUrl();
129129
assertThat(redirectedUrl).isNotNull();
130-
assertThat(redirectedUrl).matches("http://127.0.0.1:8080/authorized\\?code=.{15,}&state=state");
130+
assertThat(redirectedUrl).matches("http://127.0.0.1:8080/\\S+\\?code=.{15,}&state=state");
131131

132132
String locationHeader = URLDecoder.decode(redirectedUrl, StandardCharsets.UTF_8.name());
133133
UriComponents uriComponents = UriComponentsBuilder.fromUriString(locationHeader).build();

docs/src/docs/asciidoc/examples/src/test/java/sample/gettingStarted/SecurityConfigTests.java

Lines changed: 4 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import org.junit.jupiter.api.Test;
2222
import org.junit.jupiter.api.extension.ExtendWith;
2323
import sample.AuthorizationCodeGrantFlow;
24-
import sample.DeviceAuthorizationGrantFlow;
2524
import sample.test.SpringTestContext;
2625
import sample.test.SpringTestContextExtension;
2726

@@ -32,6 +31,7 @@
3231
import org.springframework.context.annotation.Import;
3332
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
3433
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
34+
import org.springframework.security.oauth2.core.oidc.OidcScopes;
3535
import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames;
3636
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationConsentService;
3737
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationService;
@@ -77,13 +77,13 @@ public void oidcLoginWhenGettingStartedConfigUsedThenSuccess() throws Exception
7777
assertThat(this.authorizationService).isInstanceOf(InMemoryOAuth2AuthorizationService.class);
7878
assertThat(this.authorizationConsentService).isInstanceOf(InMemoryOAuth2AuthorizationConsentService.class);
7979

80-
RegisteredClient registeredClient = this.registeredClientRepository.findByClientId("messaging-client");
80+
RegisteredClient registeredClient = this.registeredClientRepository.findByClientId("oidc-client");
8181
assertThat(registeredClient).isNotNull();
8282

8383
AuthorizationCodeGrantFlow authorizationCodeGrantFlow = new AuthorizationCodeGrantFlow(this.mockMvc);
8484
authorizationCodeGrantFlow.setUsername("user");
85-
authorizationCodeGrantFlow.addScope("message.read");
86-
authorizationCodeGrantFlow.addScope("message.write");
85+
authorizationCodeGrantFlow.addScope(OidcScopes.OPENID);
86+
authorizationCodeGrantFlow.addScope(OidcScopes.PROFILE);
8787

8888
String state = authorizationCodeGrantFlow.authorize(registeredClient);
8989
assertThatAuthorization(state, OAuth2ParameterNames.STATE).isNotNull();
@@ -117,53 +117,6 @@ public void oidcLoginWhenGettingStartedConfigUsedThenSuccess() throws Exception
117117
StringUtils.delimitedListToStringArray(scopes, " "));
118118
}
119119

120-
@Test
121-
public void deviceAuthorizationWhenGettingStartedConfigUsedThenSuccess() throws Exception {
122-
this.spring.register(AuthorizationServerConfig.class).autowire();
123-
assertThat(this.registeredClientRepository).isInstanceOf(InMemoryRegisteredClientRepository.class);
124-
assertThat(this.authorizationService).isInstanceOf(InMemoryOAuth2AuthorizationService.class);
125-
assertThat(this.authorizationConsentService).isInstanceOf(InMemoryOAuth2AuthorizationConsentService.class);
126-
127-
RegisteredClient registeredClient = this.registeredClientRepository.findByClientId("messaging-client");
128-
assertThat(registeredClient).isNotNull();
129-
130-
DeviceAuthorizationGrantFlow deviceAuthorizationGrantFlow = new DeviceAuthorizationGrantFlow(this.mockMvc);
131-
deviceAuthorizationGrantFlow.setUsername("user");
132-
deviceAuthorizationGrantFlow.addScope("message.read");
133-
deviceAuthorizationGrantFlow.addScope("message.write");
134-
135-
Map<String, Object> deviceAuthorizationResponse = deviceAuthorizationGrantFlow.authorize(registeredClient);
136-
String userCode = (String) deviceAuthorizationResponse.get(OAuth2ParameterNames.USER_CODE);
137-
assertThatAuthorization(userCode, OAuth2ParameterNames.USER_CODE).isNotNull();
138-
assertThatAuthorization(userCode, null).isNotNull();
139-
140-
String deviceCode = (String) deviceAuthorizationResponse.get(OAuth2ParameterNames.DEVICE_CODE);
141-
assertThatAuthorization(deviceCode, OAuth2ParameterNames.DEVICE_CODE).isNotNull();
142-
assertThatAuthorization(deviceCode, null).isNotNull();
143-
144-
String state = deviceAuthorizationGrantFlow.submitCode(userCode);
145-
assertThatAuthorization(state, OAuth2ParameterNames.STATE).isNotNull();
146-
assertThatAuthorization(state, null).isNotNull();
147-
148-
deviceAuthorizationGrantFlow.submitConsent(registeredClient, state, userCode);
149-
150-
Map<String, Object> tokenResponse = deviceAuthorizationGrantFlow.getTokenResponse(registeredClient, deviceCode);
151-
String accessToken = (String) tokenResponse.get(OAuth2ParameterNames.ACCESS_TOKEN);
152-
assertThatAuthorization(accessToken, OAuth2ParameterNames.ACCESS_TOKEN).isNotNull();
153-
assertThatAuthorization(accessToken, null).isNotNull();
154-
155-
String refreshToken = (String) tokenResponse.get(OAuth2ParameterNames.REFRESH_TOKEN);
156-
assertThatAuthorization(refreshToken, OAuth2ParameterNames.REFRESH_TOKEN).isNotNull();
157-
assertThatAuthorization(refreshToken, null).isNotNull();
158-
159-
String scopes = (String) tokenResponse.get(OAuth2ParameterNames.SCOPE);
160-
OAuth2AuthorizationConsent authorizationConsent = this.authorizationConsentService.findById(
161-
registeredClient.getId(), "user");
162-
assertThat(authorizationConsent).isNotNull();
163-
assertThat(authorizationConsent.getScopes()).containsExactlyInAnyOrder(
164-
StringUtils.delimitedListToStringArray(scopes, " "));
165-
}
166-
167120
private ObjectAssert<OAuth2Authorization> assertThatAuthorization(String token, String tokenType) {
168121
return assertThat(findAuthorization(token, tokenType));
169122
}

docs/src/docs/asciidoc/getting-started.adoc

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,28 @@ Spring Authorization Server can be used anywhere you already use https://docs.sp
1515

1616
The easiest way to begin using Spring Authorization Server is by creating a https://spring.io/projects/spring-boot[Spring Boot]-based application.
1717
You can use https://start.spring.io[start.spring.io] to generate a basic project or use the https://github.com/spring-projects/spring-authorization-server/tree/main/samples/default-authorizationserver[default authorization server sample] as a guide.
18-
Then add Spring Authorization Server as a dependency, as in the following example:
18+
Then add Spring Boot's starter for Spring Authorization Server as a dependency:
19+
20+
[[spring-boot-maven-dependency]]
21+
.Maven
22+
[source,xml,role="primary",subs="attributes,verbatim"]
23+
----
24+
<dependency>
25+
<groupId>org.springframework.boot</groupId>
26+
<artifactId>spring-boot-starter-oauth2-authorization-server</artifactId>
27+
</dependency>
28+
----
29+
30+
[[spring-boot-gradle-dependency]]
31+
.Gradle
32+
[source,gradle,role="secondary",subs="attributes,verbatim"]
33+
----
34+
implementation "org.springframework.boot:spring-boot-starter-oauth2-authorization-server"
35+
----
36+
37+
TIP: See https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started.html#getting-started.installing[Installing Spring Boot] for more information on using Spring Boot with Maven or Gradle.
38+
39+
Alternatively, you can add Spring Authorization Server without Spring Boot using the following example:
1940

2041
[[maven-dependency]]
2142
.Maven
@@ -35,15 +56,29 @@ Then add Spring Authorization Server as a dependency, as in the following exampl
3556
implementation "org.springframework.security:spring-security-oauth2-authorization-server:{spring-authorization-server-version}"
3657
----
3758

38-
TIP: See https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started.html#getting-started.installing[Installing Spring Boot] for more information on using Spring Boot with Maven or Gradle.
39-
4059
[[developing-your-first-application]]
4160
== Developing Your First Application
4261

43-
To get started, you need the minimum required components defined as a `@Bean` in a Spring `@Configuration`. These components can be defined as follows:
62+
To get started, you need the minimum required components defined as a `@Bean`. When using the `spring-boot-starter-oauth2-authorization-server` dependency, define the following properties and Spring Boot will provide the necessary `@Bean` definitions for you:
63+
64+
[[application-yml]]
65+
.application.yml
66+
[source,yaml]
67+
----
68+
include::{docs-java}/sample/gettingStarted/application.yml[]
69+
----
70+
71+
TIP: Beyond the Getting Started experience, most users will want to customize the default configuration. The <<defining-required-components,next section>> demonstrates providing all of the necessary beans yourself.
72+
73+
[[defining-required-components]]
74+
== Defining Required Components
75+
76+
If you want to customize the default configuration (regardless of whether you're using Spring Boot), you can define the minimum required components as a `@Bean` in a Spring `@Configuration`.
4477

4578
TIP: To skip the setup and run a working example, see the https://github.com/spring-projects/spring-authorization-server/tree/main/samples/default-authorizationserver[default authorization server sample].
4679

80+
These components can be defined as follows:
81+
4782
[[sample.gettingStarted]]
4883
include::code:SecurityConfig[]
4984

0 commit comments

Comments
 (0)