Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DEMO
spring-boot
Commits
bc6e4e6e
Commit
bc6e4e6e
authored
Aug 07, 2018
by
Madhura Bhave
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add auto-config for reactive OAuth2 Resource Server
Closes gh-13948
parent
319fec4b
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
558 additions
and
2 deletions
+558
-2
ReactiveOAuth2ResourceServerAutoConfiguration.java
...active/ReactiveOAuth2ResourceServerAutoConfiguration.java
+46
-0
ReactiveOAuth2ResourceServerJwkConfiguration.java
...eactive/ReactiveOAuth2ResourceServerJwkConfiguration.java
+49
-0
ReactiveOAuth2ResourceServerWebSecurityConfiguration.java
...ReactiveOAuth2ResourceServerWebSecurityConfiguration.java
+50
-0
package-info.java
...igure/security/oauth2/resource/reactive/package-info.java
+20
-0
spring.factories
...utoconfigure/src/main/resources/META-INF/spring.factories
+1
-0
ReactiveOAuth2ResourceServerAutoConfigurationTests.java
...e/ReactiveOAuth2ResourceServerAutoConfigurationTests.java
+156
-0
pom.xml
spring-boot-project/spring-boot-dependencies/pom.xml
+1
-1
spring-boot-features.adoc
...ing-boot-docs/src/main/asciidoc/spring-boot-features.adoc
+4
-1
README.adoc
spring-boot-samples/README.adoc
+3
-0
pom.xml
...pring-boot-sample-reactive-oauth2-resource-server/pom.xml
+60
-0
ExampleController.java
...c/main/java/sample/oauth2/resource/ExampleController.java
+32
-0
SampleReactiveOAuth2ResourceServerApplication.java
...source/SampleReactiveOAuth2ResourceServerApplication.java
+29
-0
application.yml
...oauth2-resource-server/src/main/resources/application.yml
+8
-0
SampleReactiveOAuth2ResourceServerApplicationTests.java
...e/SampleReactiveOAuth2ResourceServerApplicationTests.java
+99
-0
No files found.
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfiguration.java
0 → 100644
View file @
bc6e4e6e
/*
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
springframework
.
boot
.
autoconfigure
.
security
.
oauth2
.
resource
.
reactive
;
import
org.springframework.boot.autoconfigure.AutoConfigureBefore
;
import
org.springframework.boot.autoconfigure.EnableAutoConfiguration
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnClass
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication
;
import
org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties
;
import
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration
;
import
org.springframework.boot.context.properties.EnableConfigurationProperties
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Import
;
import
org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity
;
import
org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken
;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Reactive OAuth2 resource server
* support.
*
* @author Madhura Bhave
* @since 2.1.0
*/
@Configuration
@AutoConfigureBefore
(
ReactiveSecurityAutoConfiguration
.
class
)
@EnableConfigurationProperties
(
OAuth2ResourceServerProperties
.
class
)
@ConditionalOnClass
({
EnableWebFluxSecurity
.
class
,
BearerTokenAuthenticationToken
.
class
})
@ConditionalOnWebApplication
(
type
=
ConditionalOnWebApplication
.
Type
.
REACTIVE
)
@Import
({
ReactiveOAuth2ResourceServerJwkConfiguration
.
class
,
ReactiveOAuth2ResourceServerWebSecurityConfiguration
.
class
})
public
class
ReactiveOAuth2ResourceServerAutoConfiguration
{
}
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerJwkConfiguration.java
0 → 100644
View file @
bc6e4e6e
/*
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
springframework
.
boot
.
autoconfigure
.
security
.
oauth2
.
resource
.
reactive
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
;
import
org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder
;
import
org.springframework.security.oauth2.jwt.ReactiveJwtDecoder
;
/**
* Configures a {@link ReactiveJwtDecoder} when a JWK Set URI is available.
*
* @author Madhura Bhave
*/
@Configuration
class
ReactiveOAuth2ResourceServerJwkConfiguration
{
private
final
OAuth2ResourceServerProperties
properties
;
ReactiveOAuth2ResourceServerJwkConfiguration
(
OAuth2ResourceServerProperties
properties
)
{
this
.
properties
=
properties
;
}
@Bean
@ConditionalOnProperty
(
name
=
"spring.security.oauth2.resource.jwt.jwk.set-uri"
)
@ConditionalOnMissingBean
public
ReactiveJwtDecoder
jwtDecoder
()
{
return
new
NimbusReactiveJwtDecoder
(
this
.
properties
.
getJwt
().
getJwk
().
getSetUri
());
}
}
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerWebSecurityConfiguration.java
0 → 100644
View file @
bc6e4e6e
/*
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
springframework
.
boot
.
autoconfigure
.
security
.
oauth2
.
resource
.
reactive
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnBean
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.security.config.web.server.ServerHttpSecurity
;
import
org.springframework.security.oauth2.jwt.ReactiveJwtDecoder
;
import
org.springframework.security.web.server.SecurityWebFilterChain
;
/**
* Configures a {@link SecurityWebFilterChain} for Reactive OAuth2 resource server support
* if a {@link ReactiveJwtDecoder} bean is present.
*
* @author Madhura Bhave
*/
@Configuration
@ConditionalOnBean
(
ReactiveJwtDecoder
.
class
)
class
ReactiveOAuth2ResourceServerWebSecurityConfiguration
{
private
final
ReactiveJwtDecoder
jwtDecoder
;
ReactiveOAuth2ResourceServerWebSecurityConfiguration
(
ReactiveJwtDecoder
jwtDecoder
)
{
this
.
jwtDecoder
=
jwtDecoder
;
}
@Bean
@ConditionalOnMissingBean
public
SecurityWebFilterChain
springSecurityFilterChain
(
ServerHttpSecurity
http
)
{
http
.
authorizeExchange
().
anyExchange
().
authenticated
().
and
().
oauth2
()
.
resourceServer
().
jwt
().
jwtDecoder
(
this
.
jwtDecoder
);
return
http
.
build
();
}
}
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/package-info.java
0 → 100644
View file @
bc6e4e6e
/*
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Auto-configuration for Spring Security's Reactive OAuth2 resource server.
*/
package
org
.
springframework
.
boot
.
autoconfigure
.
security
.
oauth2
.
resource
.
reactive
;
spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories
View file @
bc6e4e6e
...
...
@@ -106,6 +106,7 @@ org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskExecutorAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
...
...
spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java
0 → 100644
View file @
bc6e4e6e
/*
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
springframework
.
boot
.
autoconfigure
.
security
.
oauth2
.
resource
.
reactive
;
import
java.util.List
;
import
org.junit.Test
;
import
org.springframework.boot.autoconfigure.AutoConfigurations
;
import
org.springframework.boot.test.context.FilteredClassLoader
;
import
org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext
;
import
org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.security.authentication.ReactiveAuthenticationManager
;
import
org.springframework.security.config.BeanIds
;
import
org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity
;
import
org.springframework.security.config.web.server.ServerHttpSecurity
;
import
org.springframework.security.core.userdetails.MapReactiveUserDetailsService
;
import
org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder
;
import
org.springframework.security.oauth2.jwt.ReactiveJwtDecoder
;
import
org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken
;
import
org.springframework.security.oauth2.server.resource.authentication.JwtReactiveAuthenticationManager
;
import
org.springframework.security.web.server.MatcherSecurityWebFilterChain
;
import
org.springframework.security.web.server.SecurityWebFilterChain
;
import
org.springframework.security.web.server.authentication.AuthenticationWebFilter
;
import
org.springframework.test.util.ReflectionTestUtils
;
import
org.springframework.web.server.WebFilter
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
import
static
org
.
mockito
.
Mockito
.
mock
;
/**
* Tests for {@link ReactiveOAuth2ResourceServerAutoConfiguration}.
*
* @author Madhura Bhave
*/
public
class
ReactiveOAuth2ResourceServerAutoConfigurationTests
{
private
ReactiveWebApplicationContextRunner
contextRunner
=
new
ReactiveWebApplicationContextRunner
()
.
withConfiguration
(
AutoConfigurations
.
of
(
ReactiveOAuth2ResourceServerAutoConfiguration
.
class
))
.
withUserConfiguration
(
TestConfig
.
class
);
@Test
public
void
autoConfigurationShouldConfigureResourceServer
()
{
this
.
contextRunner
.
withPropertyValues
(
"spring.security.oauth2.resource.jwt.jwk.set-uri=http://jwk-set-uri.com"
)
.
run
((
context
)
->
{
assertThat
(
context
.
getBean
(
ReactiveJwtDecoder
.
class
))
.
isInstanceOf
(
NimbusReactiveJwtDecoder
.
class
);
assertFilterConfiguredWithJwtAuthenticationManager
(
context
);
});
}
@Test
public
void
autoConfigurationWhenJwkSetUriNullShouldNotFail
()
{
this
.
contextRunner
.
run
((
context
)
->
assertThat
(
context
)
.
doesNotHaveBean
(
BeanIds
.
SPRING_SECURITY_FILTER_CHAIN
));
}
@Test
public
void
jwtDecoderBeanIsConditionalOnMissingBean
()
{
this
.
contextRunner
.
withPropertyValues
(
"spring.security.oauth2.resource.jwt.jwk.set-uri=http://jwk-set-uri.com"
)
.
withUserConfiguration
(
JwtDecoderConfig
.
class
)
.
run
((
this
::
assertFilterConfiguredWithJwtAuthenticationManager
));
}
@Test
public
void
autoConfigurationShouldBeConditionalOnBearerTokenAuthenticationTokenClass
()
{
this
.
contextRunner
.
withPropertyValues
(
"spring.security.oauth2.resource.jwt.jwk.set-uri=http://jwk-set-uri.com"
)
.
withUserConfiguration
(
JwtDecoderConfig
.
class
)
.
withClassLoader
(
new
FilteredClassLoader
(
BearerTokenAuthenticationToken
.
class
))
.
run
((
context
)
->
assertThat
(
context
)
.
doesNotHaveBean
(
BeanIds
.
SPRING_SECURITY_FILTER_CHAIN
));
}
@Test
public
void
autoConfigurationWhenSecurityWebFilterChainConfigPresentShouldNotAddOne
()
{
this
.
contextRunner
.
withPropertyValues
(
"spring.security.oauth2.resource.jwt.jwk.set-uri=http://jwk-set-uri.com"
)
.
withUserConfiguration
(
SecurityWebFilterChainConfig
.
class
)
.
run
((
context
)
->
{
assertThat
(
context
).
hasSingleBean
(
SecurityWebFilterChain
.
class
);
assertThat
(
context
).
hasBean
(
"testSpringSecurityFilterChain"
);
});
}
@SuppressWarnings
(
"unchecked"
)
private
void
assertFilterConfiguredWithJwtAuthenticationManager
(
AssertableReactiveWebApplicationContext
context
)
{
MatcherSecurityWebFilterChain
filterChain
=
(
MatcherSecurityWebFilterChain
)
context
.
getBean
(
BeanIds
.
SPRING_SECURITY_FILTER_CHAIN
);
List
<
WebFilter
>
filters
=
(
List
<
WebFilter
>)
ReflectionTestUtils
.
getField
(
filterChain
,
"filters"
);
AuthenticationWebFilter
webFilter
=
(
AuthenticationWebFilter
)
filters
.
stream
()
.
filter
((
f
)
->
f
instanceof
AuthenticationWebFilter
).
findFirst
()
.
orElse
(
null
);
ReactiveAuthenticationManager
authenticationManager
=
(
ReactiveAuthenticationManager
)
ReflectionTestUtils
.
getField
(
webFilter
,
"authenticationManager"
);
assertThat
(
authenticationManager
)
.
isInstanceOf
(
JwtReactiveAuthenticationManager
.
class
);
}
@EnableWebFluxSecurity
static
class
TestConfig
{
@Bean
public
MapReactiveUserDetailsService
userDetailsService
()
{
return
mock
(
MapReactiveUserDetailsService
.
class
);
}
}
@Configuration
static
class
JwtDecoderConfig
{
@Bean
public
ReactiveJwtDecoder
decoder
()
{
return
mock
(
ReactiveJwtDecoder
.
class
);
}
}
@Configuration
static
class
SecurityWebFilterChainConfig
{
@Bean
SecurityWebFilterChain
testSpringSecurityFilterChain
(
ServerHttpSecurity
http
,
ReactiveJwtDecoder
decoder
)
{
http
.
authorizeExchange
().
pathMatchers
(
"/message/**"
).
hasRole
(
"ADMIN"
)
.
anyExchange
().
authenticated
().
and
().
oauth2
().
resourceServer
().
jwt
()
.
jwtDecoder
(
decoder
);
return
http
.
build
();
}
}
}
spring-boot-project/spring-boot-dependencies/pom.xml
View file @
bc6e4e6e
...
...
@@ -165,7 +165,7 @@
<spring-plugin.version>
1.2.0.RELEASE
</spring-plugin.version>
<spring-restdocs.version>
2.0.2.RELEASE
</spring-restdocs.version>
<spring-retry.version>
1.2.2.RELEASE
</spring-retry.version>
<spring-security.version>
5.1.0.
M2
</spring-security.version>
<spring-security.version>
5.1.0.
BUILD-SNAPSHOT
</spring-security.version>
<spring-session-bom.version>
Bean-M1
</spring-session-bom.version>
<spring-ws.version>
3.0.3.RELEASE
</spring-ws.version>
<sqlite-jdbc.version>
3.23.1
</sqlite-jdbc.version>
...
...
spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc
View file @
bc6e4e6e
...
...
@@ -3286,7 +3286,10 @@ following example:
spring.security.oauth2.resource.jwt.jwk.set-uri=https://example.com/oauth2/default/v1/keys
----
Alternatively, you can define your own `JwtDecoder` bean.
The same properties are applicable for both servlet and reactive applications.
Alternatively, you can define your own `JwtDecoder` bean for servlet applications
or a `ReactiveJwtDecoder` for reactive applications.
...
...
spring-boot-samples/README.adoc
View file @
bc6e4e6e
...
...
@@ -137,6 +137,9 @@ The following sample applications are provided:
| link:spring-boot-sample-oauth2-resource-server[spring-boot-sample-oauth2-resource-server]
| Configure an OAuth2 resource server
| link:spring-boot-sample-reactive-oauth2-resource-server[spring-boot-sample-reactive-oauth2-resource-server]
| Configure a Reactive OAuth2 resource server
| link:spring-boot-sample-parent-context[spring-boot-sample-parent-context]
| Application that uses an `ApplicationContext` with a parent
...
...
spring-boot-samples/spring-boot-sample-reactive-oauth2-resource-server/pom.xml
0 → 100644
View file @
bc6e4e6e
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<parent>
<!-- Your own application should inherit from spring-boot-starter-parent -->
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-samples
</artifactId>
<version>
${revision}
</version>
</parent>
<artifactId>
spring-boot-sample-reactive-oauth2-resource-server
</artifactId>
<name>
Spring Boot Sample Reactive OAuth2 Resource Server
</name>
<description>
Spring Boot Sample Reactive Resource Server
</description>
<properties>
<main.basedir>
${basedir}/../..
</main.basedir>
</properties>
<dependencies>
<!-- Compile -->
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-security
</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-webflux
</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.security
</groupId>
<artifactId>
spring-security-config
</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.security
</groupId>
<artifactId>
spring-security-oauth2-jose
</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.security
</groupId>
<artifactId>
spring-security-oauth2-resource-server
</artifactId>
</dependency>
<!-- Test -->
<dependency>
<groupId>
com.squareup.okhttp3
</groupId>
<artifactId>
mockwebserver
</artifactId>
<version>
3.9.0
</version>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-test
</artifactId>
<scope>
test
</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-maven-plugin
</artifactId>
</plugin>
</plugins>
</build>
</project>
spring-boot-samples/spring-boot-sample-reactive-oauth2-resource-server/src/main/java/sample/oauth2/resource/ExampleController.java
0 → 100644
View file @
bc6e4e6e
/*
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
sample
.
oauth2
.
resource
;
import
org.springframework.security.core.annotation.AuthenticationPrincipal
;
import
org.springframework.security.oauth2.jwt.Jwt
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RestController
;
@RestController
public
class
ExampleController
{
@GetMapping
(
"/"
)
public
String
index
(
@AuthenticationPrincipal
Jwt
jwt
)
{
return
String
.
format
(
"Hello, %s!"
,
jwt
.
getSubject
());
}
}
spring-boot-samples/spring-boot-sample-reactive-oauth2-resource-server/src/main/java/sample/oauth2/resource/SampleReactiveOAuth2ResourceServerApplication.java
0 → 100644
View file @
bc6e4e6e
/*
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
sample
.
oauth2
.
resource
;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
@SpringBootApplication
public
class
SampleReactiveOAuth2ResourceServerApplication
{
public
static
void
main
(
String
[]
args
)
{
SpringApplication
.
run
(
SampleReactiveOAuth2ResourceServerApplication
.
class
);
}
}
spring-boot-samples/spring-boot-sample-reactive-oauth2-resource-server/src/main/resources/application.yml
0 → 100644
View file @
bc6e4e6e
spring
:
security
:
oauth2
:
resource
:
jwt
:
jwk
:
# To run the application, replace this with a valid JWK Set URI
set-uri
:
https://example.com/oauth2/default/v1/keys
\ No newline at end of file
spring-boot-samples/spring-boot-sample-reactive-oauth2-resource-server/src/test/java/sample/oauth2/resource/SampleReactiveOAuth2ResourceServerApplicationTests.java
0 → 100644
View file @
bc6e4e6e
/*
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
sample
.
oauth2
.
resource
;
import
okhttp3.mockwebserver.MockResponse
;
import
okhttp3.mockwebserver.MockWebServer
;
import
org.junit.AfterClass
;
import
org.junit.BeforeClass
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.boot.test.context.SpringBootTest
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.http.MediaType
;
import
org.springframework.test.context.junit4.SpringRunner
;
import
org.springframework.test.web.reactive.server.WebTestClient
;
@RunWith
(
SpringRunner
.
class
)
@SpringBootTest
(
webEnvironment
=
SpringBootTest
.
WebEnvironment
.
RANDOM_PORT
)
public
class
SampleReactiveOAuth2ResourceServerApplicationTests
{
@Autowired
private
WebTestClient
webTestClient
;
private
static
MockWebServer
server
=
new
MockWebServer
();
private
static
final
String
VALID_TOKEN
=
"eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJzdWJqZWN0Iiwic2NvcGUiOiJtZXNzYWdlOnJlYWQi"
+
"LCJleHAiOjQ2ODM4MDUxNDF9.h-j6FKRFdnTdmAueTZCdep45e6DPwqM68ZQ8doIJ1exi9YxAlbWzOwId6Bd0L5YmCmp63gGQgsBUBLzwnZQ8kLUgU"
+
"OBEC3UzSWGRqMskCY9_k9pX0iomX6IfF3N0PaYs0WPC4hO1s8wfZQ-6hKQ4KigFi13G9LMLdH58PRMK0pKEvs3gCbHJuEPw-K5ORlpdnleUTQIwIN"
+
"afU57cmK3KocTeknPAM_L716sCuSYGvDl6xUTXO7oPdrXhS_EhxLP6KxrpI1uD4Ea_5OWTh7S0Wx5LLDfU6wBG1DowN20d374zepOIEkR-Jnmr_Ql"
+
"R44vmRqS5ncrF-1R0EGcPX49U6A"
;
@BeforeClass
public
static
void
setup
()
throws
Exception
{
server
.
start
();
String
url
=
server
.
url
(
"/.well-known/jwks.json"
).
toString
();
server
.
enqueue
(
mockResponse
());
System
.
setProperty
(
"spring.security.oauth2.resource.jwt.jwk.set-uri"
,
url
);
}
@AfterClass
public
static
void
shutdown
()
throws
Exception
{
server
.
shutdown
();
System
.
clearProperty
(
"spring.security.oauth2.resource.jwt.jwk.set-uri"
);
}
@Test
public
void
getWhenValidTokenShouldBeOk
()
{
this
.
webTestClient
.
get
().
uri
(
"/"
)
.
headers
(
headers
->
headers
.
setBearerAuth
(
VALID_TOKEN
)).
exchange
()
.
expectStatus
().
isOk
().
expectBody
(
String
.
class
)
.
isEqualTo
(
"Hello, subject!"
);
}
@Test
public
void
getWhenNoTokenShouldBeUnauthorized
()
{
this
.
webTestClient
.
get
().
uri
(
"/"
).
exchange
().
expectStatus
().
isUnauthorized
()
.
expectHeader
().
valueEquals
(
HttpHeaders
.
WWW_AUTHENTICATE
,
"Bearer"
);
}
private
static
MockResponse
mockResponse
()
{
String
body
=
"{\"keys\":[{\"p\":\"2p-ViY7DE9ZrdWQb544m0Jp7Cv03YCSljqfim9pD4ALhObX0OrAznOiowTjwBky9JGffMw"
+
"DBVSfJSD9TSU7aH2sbbfi0bZLMdekKAuimudXwUqPDxrrg0BCyvCYgLmKjbVT3zcdylWSog93CNTxGDPzauu-oc0XPNKCXnaDpNvE\""
+
",\"kty\":\"RSA\",\"q\":\"sP_QYavrpBvSJ86uoKVGj2AGl78CSsAtpf1ybSY5TwUlorXSdqapRbY69Y271b0aMLzlleUn9ZTBO"
+
"1dlKV2_dw_lPADHVia8z3pxL-8sUhIXLsgj4acchMk4c9YX-sFh07xENnyZ-_TXm3llPLuL67HUfBC2eKe800TmCYVWc9U\",\"d\""
+
":\"bn1nFxCQT4KLTHqo8mo9HvHD0cRNRNdWcKNnnEQkCF6tKbt-ILRyQGP8O40axLd7CoNVG9c9p_-g4-2kwCtLJNv_STLtwfpCY7"
+
"VN5o6-ZIpfTjiW6duoPrLWq64Hm_4LOBQTiZfUPcLhsuJRHbWqakj-kV_YbUyC2Ocf_dd8IAQcSrAU2SCcDebhDCWwRUFvaa9V5eq0"
+
"851S9goaA-AJz-JXyePH6ZFr8JxmWkWxYZ5kdcMD-sm9ZbxE0CaEk32l4fE4hR-L8x2dDtjWA-ahKCZ091z-gV3HWtR2JOjvxoNRjxUo"
+
"3UxaGiFJHWNIl0EYUJZu1Cb-5wIlEI7wPx5mwQ\",\"e\":\"AQAB\",\"use\":\"sig\",\"kid\":\"one\",\"qi\":\"qS0OK4"
+
"8M2CIAA6_4Wdw4EbCaAfcTLf5Oy9t5BOF_PFUKqoSpZ6JsT5H0a_4zkjt-oI969v78OTlvBKbmEyKO-KeytzHBAA5CsLmVcz0THrMSg6o"
+
"XZqu66MPnvWoZN9FEN5TklPOvBFm8Bg1QZ3k-YMVaM--DLvhaYR95_mqaz50\",\"dp\":\"Too2NozLGD1XrXyhabZvy1E0EuaVFj0UHQ"
+
"PDLSpkZ_2g3BK6Art6T0xmE8RYtmqrKIEIdlI3IliAvyvAx_1D7zWTTRaj-xlZyqJFrnXWL7zj8UxT8PkB-r2E-ILZ3NAi1gxIWezlBTZ8"
+
"M6NfObDFmbTc_3tJkN_raISo8z_ziIE\",\"dq\":\"U0yhSkY5yOsa9YcMoigGVBWSJLpNHtbg5NypjHrPv8OhWbkOSq7WvSstBkF"
+
"k5AtyFvvfZLMLIkWWxxGzV0t6f1MoxBtttLrYYyCxwihiiGFhLbAdSuZ1wnxcqA9bC7UVECvrQmVTpsMs8UupfHKbQBpZ8OWAqrn"
+
"uYNNtG4_4Bt0\",\"n\":\"lygtuZj0lJjqOqIWocF8Bb583QDdq-aaFg8PesOp2-EDda6GqCpL-_NZVOflNGX7XIgjsWHcPsQHs"
+
"V9gWuOzSJ0iEuWvtQ6eGBP5M6m7pccLNZfwUse8Cb4Ngx3XiTlyuqM7pv0LPyppZusfEHVEdeelou7Dy9k0OQ_nJTI3b2E1WBoHC5"
+
"8CJ453lo4gcBm1efURN3LIVc1V9NQY_ESBKVdwqYyoJPEanURLVGRd6cQKn6YrCbbIRHjqAyqOE-z3KmgDJnPriljfR5XhSGyM9eq"
+
"D9Xpy6zu_MAeMJJfSArp857zLPk-Wf5VP9STAcjyfdBIybMKnwBYr2qHMT675hQ\"}]}"
;
return
new
MockResponse
()
.
setHeader
(
HttpHeaders
.
CONTENT_TYPE
,
MediaType
.
APPLICATION_JSON_VALUE
)
.
setResponseCode
(
200
).
setBody
(
body
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment