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
f714b1d4
Commit
f714b1d4
authored
Jan 16, 2017
by
Stephane Nicoll
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '1.5.x'
parents
9a4b6a90
ada441bc
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
147 additions
and
80 deletions
+147
-80
DefaultUserInfoRestTemplateFactory.java
...y/oauth2/resource/DefaultUserInfoRestTemplateFactory.java
+95
-0
ResourceServerTokenServicesConfiguration.java
...h2/resource/ResourceServerTokenServicesConfiguration.java
+2
-2
UserInfoRestTemplateFactory.java
...security/oauth2/resource/UserInfoRestTemplateFactory.java
+12
-69
ResourceServerTokenServicesConfigurationTests.java
...source/ResourceServerTokenServicesConfigurationTests.java
+29
-1
spring-boot-features.adoc
spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc
+9
-8
No files found.
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/DefaultUserInfoRestTemplateFactory.java
0 → 100644
View file @
f714b1d4
/*
* Copyright 2012-2017 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
;
import
java.util.List
;
import
org.springframework.beans.factory.ObjectProvider
;
import
org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerTokenServicesConfiguration.AcceptJsonRequestEnhancer
;
import
org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerTokenServicesConfiguration.AcceptJsonRequestInterceptor
;
import
org.springframework.core.annotation.AnnotationAwareOrderComparator
;
import
org.springframework.security.oauth2.client.OAuth2ClientContext
;
import
org.springframework.security.oauth2.client.OAuth2RestTemplate
;
import
org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails
;
import
org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider
;
import
org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails
;
import
org.springframework.util.CollectionUtils
;
/**
* Factory used to create the {@link OAuth2RestTemplate} used for extracting user info
* during authentication if none is available.
*
* @author Dave Syer
* @author Stephane Nicoll
* @since 1.5.0
*/
public
class
DefaultUserInfoRestTemplateFactory
implements
UserInfoRestTemplateFactory
{
private
static
final
AuthorizationCodeResourceDetails
DEFAULT_RESOURCE_DETAILS
;
static
{
AuthorizationCodeResourceDetails
details
=
new
AuthorizationCodeResourceDetails
();
details
.
setClientId
(
"<N/A>"
);
details
.
setUserAuthorizationUri
(
"Not a URI because there is no client"
);
details
.
setAccessTokenUri
(
"Not a URI because there is no client"
);
DEFAULT_RESOURCE_DETAILS
=
details
;
}
private
final
List
<
UserInfoRestTemplateCustomizer
>
customizers
;
private
final
OAuth2ProtectedResourceDetails
details
;
private
final
OAuth2ClientContext
oauth2ClientContext
;
private
OAuth2RestTemplate
oauth2RestTemplate
;
public
DefaultUserInfoRestTemplateFactory
(
ObjectProvider
<
List
<
UserInfoRestTemplateCustomizer
>>
customizers
,
ObjectProvider
<
OAuth2ProtectedResourceDetails
>
details
,
ObjectProvider
<
OAuth2ClientContext
>
oauth2ClientContext
)
{
this
.
customizers
=
customizers
.
getIfAvailable
();
this
.
details
=
details
.
getIfAvailable
();
this
.
oauth2ClientContext
=
oauth2ClientContext
.
getIfAvailable
();
}
public
OAuth2RestTemplate
getUserInfoRestTemplate
()
{
if
(
this
.
oauth2RestTemplate
==
null
)
{
this
.
oauth2RestTemplate
=
createOAuth2RestTemplate
(
this
.
details
==
null
?
DEFAULT_RESOURCE_DETAILS
:
this
.
details
);
this
.
oauth2RestTemplate
.
getInterceptors
().
add
(
new
AcceptJsonRequestInterceptor
());
AuthorizationCodeAccessTokenProvider
accessTokenProvider
=
new
AuthorizationCodeAccessTokenProvider
();
accessTokenProvider
.
setTokenRequestEnhancer
(
new
AcceptJsonRequestEnhancer
());
this
.
oauth2RestTemplate
.
setAccessTokenProvider
(
accessTokenProvider
);
if
(!
CollectionUtils
.
isEmpty
(
this
.
customizers
))
{
AnnotationAwareOrderComparator
.
sort
(
this
.
customizers
);
for
(
UserInfoRestTemplateCustomizer
customizer
:
this
.
customizers
)
{
customizer
.
customize
(
this
.
oauth2RestTemplate
);
}
}
}
return
this
.
oauth2RestTemplate
;
}
private
OAuth2RestTemplate
createOAuth2RestTemplate
(
OAuth2ProtectedResourceDetails
details
)
{
if
(
this
.
oauth2ClientContext
==
null
)
{
return
new
OAuth2RestTemplate
(
details
);
}
return
new
OAuth2RestTemplate
(
details
,
this
.
oauth2ClientContext
);
}
}
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/ResourceServerTokenServicesConfiguration.java
View file @
f714b1d4
/*
* Copyright 2012-201
6
the original author or authors.
* Copyright 2012-201
7
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.
...
...
@@ -88,7 +88,7 @@ public class ResourceServerTokenServicesConfiguration {
ObjectProvider
<
List
<
UserInfoRestTemplateCustomizer
>>
customizers
,
ObjectProvider
<
OAuth2ProtectedResourceDetails
>
details
,
ObjectProvider
<
OAuth2ClientContext
>
oauth2ClientContext
)
{
return
new
UserInfoRestTemplateFactory
(
customizers
,
details
,
oauth2ClientContext
);
return
new
Default
UserInfoRestTemplateFactory
(
customizers
,
details
,
oauth2ClientContext
);
}
@Configuration
...
...
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/UserInfoRestTemplateFactory.java
View file @
f714b1d4
/*
* Copyright 2012-201
6
the original author or authors.
* Copyright 2012-201
7
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.
...
...
@@ -16,80 +16,23 @@
package
org
.
springframework
.
boot
.
autoconfigure
.
security
.
oauth2
.
resource
;
import
java.util.List
;
import
org.springframework.beans.factory.ObjectProvider
;
import
org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerTokenServicesConfiguration.AcceptJsonRequestEnhancer
;
import
org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerTokenServicesConfiguration.AcceptJsonRequestInterceptor
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.core.annotation.AnnotationAwareOrderComparator
;
import
org.springframework.security.oauth2.client.OAuth2ClientContext
;
import
org.springframework.security.oauth2.client.OAuth2RestTemplate
;
import
org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails
;
import
org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider
;
import
org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails
;
import
org.springframework.util.CollectionUtils
;
/**
* Factory used to create the
rest template used for extracting user info during
*
authentication
.
* Factory used to create the
{@link OAuth2RestTemplate} used for extracting user info
*
during authentication if none is available
.
*
* @author Dave Syer
* @author Stephane Nicoll
* @since 1.4.0
*/
@Configuration
public
class
UserInfoRestTemplateFactory
{
private
static
final
AuthorizationCodeResourceDetails
DEFAULT_RESOURCE_DETAILS
;
static
{
AuthorizationCodeResourceDetails
details
=
new
AuthorizationCodeResourceDetails
();
details
.
setClientId
(
"<N/A>"
);
details
.
setUserAuthorizationUri
(
"Not a URI because there is no client"
);
details
.
setAccessTokenUri
(
"Not a URI because there is no client"
);
DEFAULT_RESOURCE_DETAILS
=
details
;
}
private
final
List
<
UserInfoRestTemplateCustomizer
>
customizers
;
private
final
OAuth2ProtectedResourceDetails
details
;
private
final
OAuth2ClientContext
oauth2ClientContext
;
private
OAuth2RestTemplate
template
;
public
UserInfoRestTemplateFactory
(
ObjectProvider
<
List
<
UserInfoRestTemplateCustomizer
>>
customizers
,
ObjectProvider
<
OAuth2ProtectedResourceDetails
>
details
,
ObjectProvider
<
OAuth2ClientContext
>
oauth2ClientContext
)
{
this
.
customizers
=
customizers
.
getIfAvailable
();
this
.
details
=
details
.
getIfAvailable
();
this
.
oauth2ClientContext
=
oauth2ClientContext
.
getIfAvailable
();
}
public
OAuth2RestTemplate
getUserInfoRestTemplate
()
{
if
(
this
.
template
==
null
)
{
this
.
template
=
getTemplate
(
this
.
details
==
null
?
DEFAULT_RESOURCE_DETAILS
:
this
.
details
);
this
.
template
.
getInterceptors
().
add
(
new
AcceptJsonRequestInterceptor
());
AuthorizationCodeAccessTokenProvider
accessTokenProvider
=
new
AuthorizationCodeAccessTokenProvider
();
accessTokenProvider
.
setTokenRequestEnhancer
(
new
AcceptJsonRequestEnhancer
());
this
.
template
.
setAccessTokenProvider
(
accessTokenProvider
);
if
(!
CollectionUtils
.
isEmpty
(
this
.
customizers
))
{
AnnotationAwareOrderComparator
.
sort
(
this
.
customizers
);
for
(
UserInfoRestTemplateCustomizer
customizer
:
this
.
customizers
)
{
customizer
.
customize
(
this
.
template
);
}
}
}
return
this
.
template
;
}
private
OAuth2RestTemplate
getTemplate
(
OAuth2ProtectedResourceDetails
details
)
{
if
(
this
.
oauth2ClientContext
==
null
)
{
return
new
OAuth2RestTemplate
(
details
);
}
return
new
OAuth2RestTemplate
(
details
,
this
.
oauth2ClientContext
);
}
public
interface
UserInfoRestTemplateFactory
{
/**
* Return the {@link OAuth2RestTemplate} used for extracting user info during
* authentication if none is available.
* @return the OAuth2RestTemplate used for authentication
*/
OAuth2RestTemplate
getUserInfoRestTemplate
();
}
spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/ResourceServerTokenServicesConfigurationTests.java
View file @
f714b1d4
/*
* Copyright 2012-201
6
the original author or authors.
* Copyright 2012-201
7
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.
...
...
@@ -48,6 +48,7 @@ import org.springframework.http.client.ClientHttpResponse;
import
org.springframework.security.core.GrantedAuthority
;
import
org.springframework.security.core.authority.AuthorityUtils
;
import
org.springframework.security.oauth2.client.OAuth2RestTemplate
;
import
org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails
;
import
org.springframework.security.oauth2.provider.token.DefaultTokenServices
;
import
org.springframework.security.oauth2.provider.token.RemoteTokenServices
;
import
org.springframework.social.connect.ConnectionFactoryLocator
;
...
...
@@ -213,6 +214,19 @@ public class ResourceServerTokenServicesConfigurationTests {
assertThat
(
services
).
isNotNull
();
}
@Test
public
void
customUserInfoRestTemplateFactory
()
{
EnvironmentTestUtils
.
addEnvironment
(
this
.
environment
,
"security.oauth2.resource.userInfoUri:http://example.com"
);
this
.
context
=
new
SpringApplicationBuilder
(
CustomUserInfoRestTemplateFactory
.
class
,
ResourceConfiguration
.
class
)
.
environment
(
this
.
environment
).
web
(
false
).
run
();
assertThat
(
this
.
context
.
getBeansOfType
(
UserInfoRestTemplateFactory
.
class
))
.
hasSize
(
1
);
assertThat
(
this
.
context
.
getBean
(
UserInfoRestTemplateFactory
.
class
))
.
isInstanceOf
(
CustomUserInfoRestTemplateFactory
.
class
);
}
@Configuration
@Import
({
ResourceServerTokenServicesConfiguration
.
class
,
ResourceServerPropertiesConfiguration
.
class
,
...
...
@@ -313,4 +327,18 @@ public class ResourceServerTokenServicesConfigurationTests {
}
@Component
protected
static
class
CustomUserInfoRestTemplateFactory
implements
UserInfoRestTemplateFactory
{
private
final
OAuth2RestTemplate
restTemplate
=
new
OAuth2RestTemplate
(
new
AuthorizationCodeResourceDetails
());
@Override
public
OAuth2RestTemplate
getUserInfoRestTemplate
()
{
return
this
.
restTemplate
;
}
}
}
spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc
View file @
f714b1d4
...
...
@@ -2555,14 +2555,15 @@ which suits most providers and matches the spec, but if you need to change it yo
[[boot-features-security-custom-user-info]]
=== Customizing the User Info RestTemplate
If you have a `user-info-uri`, the resource server features use an `OAuth2RestTemplate`
internally to fetch user details for authentication. This is provided as a qualified
`@Bean` with id `userInfoRestTemplate`, but you shouldn't need to know that to just
use it. The default should be fine for most providers, but occasionally you might need to
add additional interceptors, or change the request authenticator (which is how the token
gets attached to outgoing requests). To add a customization just create a bean of type
`UserInfoRestTemplateCustomizer` - it has a single method that will be called after the
bean is created but before it is initialized. The rest template that is being customized
here is _only_ used internally to carry out authentication.
internally to fetch user details for authentication. This is provided as a `@Bean` of
type `UserInfoRestTemplateFactory`. The default should be fine for most providers, but
occasionally you might need to add additional interceptors, or change the request
authenticator (which is how the token gets attached to outgoing requests). To add a
customization just create a bean of type `UserInfoRestTemplateCustomizer` - it has a
single method that will be called after the bean is created but before it is initialized.
The rest template that is being customized here is _only_ used internally to carry out
authentication. Alternatively, you could define your own `UserInfoRestTemplateFactory`
`@Bean` to take full control.
[TIP]
====
...
...
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