Remove Spring Security OAuth Auto-Configuration

This commit removes auto-configuration support for Spring Security
OAuth, paving the way for the introduction of auto-configuration for
Spring Security 5's new OAuth-related features.

Closes gh-10255
This commit is contained in:
Andy Wilkinson
2017-09-21 10:30:34 +01:00
parent a0fee6fe3b
commit e9147c2f20
79 changed files with 2 additions and 6877 deletions

View File

@@ -476,27 +476,8 @@ content into your application; rather pick only the properties that you need.
# SECURITY PROPERTIES
# ----------------------------------------
# SECURITY ({sc-spring-boot-autoconfigure}/security/SecurityProperties.{sc-ext}[SecurityProperties])
spring.security.filter.order=0 # Security filter chain order.
spring.security.filter.dispatcher-types=ASYNC,ERROR,REQUEST # Security filter chain dispatcher types.
# SECURITY OAUTH2 CLIENT ({sc-spring-boot-autoconfigure}/security/oauth2/OAuth2ClientProperties.{sc-ext}[OAuth2ClientProperties])
security.oauth2.client.client-id= # OAuth2 client id.
security.oauth2.client.client-secret= # OAuth2 client secret. A random secret is generated by default
# SECURITY OAUTH2 RESOURCES ({sc-spring-boot-autoconfigure}/security/oauth2/resource/ResourceServerProperties.{sc-ext}[ResourceServerProperties])
security.oauth2.resource.id= # Identifier of the resource.
security.oauth2.resource.jwt.key-uri= # The URI of the JWT token. Can be set if the value is not available and the key is public.
security.oauth2.resource.jwt.key-value= # The verification key of the JWT token. Can either be a symmetric secret or PEM-encoded RSA public key.
security.oauth2.resource.jwk.key-set-uri= # The URI for getting the set of keys that can be used to validate the token.
security.oauth2.resource.prefer-token-info=true # Use the token info, can be set to false to use the user info.
security.oauth2.resource.service-id=resource #
security.oauth2.resource.token-info-uri= # URI of the token decoding endpoint.
security.oauth2.resource.token-type= # The token type to send when using the userInfoUri.
security.oauth2.resource.user-info-uri= # URI of the user endpoint.
# SECURITY OAUTH2 SSO ({sc-spring-boot-autoconfigure}/security/oauth2/client/OAuth2SsoProperties.{sc-ext}[OAuth2SsoProperties])
security.oauth2.sso.login-path=/login # Path to the login page, i.e. the one that triggers the redirect to the OAuth2 Authorization Server
spring.security.filter.order=0 # Security filter chain order.
spring.security.filter.dispatcher-types=ASYNC,ERROR,REQUEST # Security filter chain dispatcher types.
# ----------------------------------------
# DATA PROPERTIES

View File

@@ -2752,238 +2752,6 @@ explicitly configure the paths that you do want to override.
[[boot-features-security-oauth2]]
=== OAuth2
If you have `spring-security-oauth2` on your classpath you can take advantage of some
auto-configuration to make it easy to set up Authorization or Resource Server. For full
details, see the {spring-security-oauth2-reference}[Spring Security OAuth 2 Developers
Guide].
[[boot-features-security-oauth2-authorization-server]]
==== Authorization Server
To create an Authorization Server and grant access tokens you need to use
`@EnableAuthorizationServer` and provide `security.oauth2.client.client-id` and
`security.oauth2.client.client-secret]` properties. The client will be registered for you
in an in-memory repository.
Having done that you will be able to use the client credentials to create an access token,
for example:
[indent=0]
----
$ curl client:secret@localhost:8080/oauth/token -d grant_type=password -d username=user -d password=pwd
----
The basic auth credentials for the `/token` endpoint are the `client-id` and
`client-secret`. The user credentials are the normal Spring Security user details (which
default in Spring Boot to "`user`" and a random password).
To switch off the auto-configuration and configure the Authorization Server features
yourself just add a `@Bean` of type `AuthorizationServerConfigurer`.
[[boot-features-security-oauth2-resource-server]]
==== Resource Server
To use the access token you need a Resource Server (which can be the same as the
Authorization Server). Creating a Resource Server is easy, just add
`@EnableResourceServer` and provide some configuration to allow the server to decode
access tokens. If your application is also an Authorization Server it already knows how
to decode tokens, so there is nothing else to do. If your app is a standalone service then you
need to give it some more configuration, one of the following options:
* `security.oauth2.resource.user-info-uri` to use the `/me` resource (e.g.
`\https://uaa.run.pivotal.io/userinfo` on Pivotal Web Services (PWS))
* `security.oauth2.resource.token-info-uri` to use the token decoding endpoint (e.g.
`\https://uaa.run.pivotal.io/check_token` on PWS).
If you specify both the `user-info-uri` and the `token-info-uri` then you can set a flag
to say that one is preferred over the other (`prefer-token-info=true` is the default).
Alternatively (instead of `user-info-uri` or `token-info-uri`) if the tokens are JWTs you
can configure a `security.oauth2.resource.jwt.key-value` to decode them locally (where the
key is a verification key). The verification key value is either a symmetric secret or
PEM-encoded RSA public key. If you don't have the key and it's public you can provide a
URI where it can be downloaded (as a JSON object with a "`value`" field) with
`security.oauth2.resource.jwt.key-uri`. E.g. on PWS:
[indent=0]
----
$ curl https://uaa.run.pivotal.io/token_key
{"alg":"SHA256withRSA","value":"-----BEGIN PUBLIC KEY-----\nMIIBI...\n-----END PUBLIC KEY-----\n"}
----
Additionally, if your authorization server has an endpoint that returns a set of JSON Web Keys(JWKs),
you can configure `security.oauth2.resource.jwk.key-set-uri`. E.g. on PWS:
[indent=0]
----
$ curl https://uaa.run.pivotal.io/token_keys
{"keys":[{"kid":"key-1","alg":"RS256","value":"-----BEGIN PUBLIC KEY-----\nMIIBI...\n-----END PUBLIC KEY-----\n"]}
----
NOTE: Configuring both JWT and JWK properties will cause an error. Only one of `security.oauth2.resource.jwt.key-uri`
(or `security.oauth2.resource.jwt.key-value`) and `security.oauth2.resource.jwk.key-set-uri` should be configured.
WARNING: If you use the `security.oauth2.resource.jwt.key-uri` or `security.oauth2.resource.jwk.key-set-uri`,
the authorization server needs to be running when your application starts up. It will log a warning if it can't
find the key, and tell you what to do to fix it.
OAuth2 resources are protected by a filter chain with order
`security.oauth2.resource.filter-order` and the default is after the filter protecting the
actuator endpoints by default (so actuator endpoints will stay on HTTP Basic unless you
change the order).
[[boot-features-security-oauth2-token-type]]
=== Token Type in User Info
Google, and certain other 3rd party identity providers, are more strict about the token
type name that is sent in the headers to the user info endpoint. The default is "`Bearer`"
which suits most providers and matches the spec, but if you need to change it you can set
`security.oauth2.resource.token-type`.
[[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 `@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]
====
To set an RSA key value in YAML use the "`pipe`" continuation marker to split it over
multiple lines ("`|`") and remember to indent the key value (it's a standard YAML
language feature). Example:
[source,yaml,indent=0]
----
security:
oauth2:
resource:
jwt:
keyValue: |
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC...
-----END PUBLIC KEY-----
----
====
[[boot-features-security-custom-user-info-client]]
==== Client
To make your web-app into an OAuth2 client you can simply add `@EnableOAuth2Client` and
Spring Boot will create an `OAuth2ClientContext` and `OAuth2ProtectedResourceDetails` that
are necessary to create an `OAuth2RestOperations`. Spring Boot does not automatically
create such bean but you can easily create your own:
[source,java,indent=0]
----
@Bean
public OAuth2RestTemplate oauth2RestTemplate(OAuth2ClientContext oauth2ClientContext,
OAuth2ProtectedResourceDetails details) {
return new OAuth2RestTemplate(details, oauth2ClientContext);
}
----
NOTE: You may want to add a qualifier and review your configuration as more than one
`RestTemplate` may be defined in your application.
This configuration uses `security.oauth2.client.*` as credentials (the same as you might
be using in the Authorization Server), but in addition it will need to know the
authorization and token URIs in the Authorization Server. For example:
.application.yml
[source,yaml,indent=0]
----
security:
oauth2:
client:
clientId: bd1c0a783ccdd1c9b9e4
clientSecret: 1a9030fbca47a5b2c28e92f19050bb77824b5ad1
accessTokenUri: https://github.com/login/oauth/access_token
userAuthorizationUri: https://github.com/login/oauth/authorize
clientAuthenticationScheme: form
----
An application with this configuration will redirect to Github for authorization when you
attempt to use the `OAuth2RestTemplate`. If you are already signed into Github you won't
even notice that it has authenticated. These specific credentials will only work if your
application is running on port 8080 (register your own client app in Github or other
provider for more flexibility).
To limit the scope that the client asks for when it obtains an access token you can set
`security.oauth2.client.scope` (comma separated or an array in YAML). By default the scope
is empty and it is up to Authorization Server to decide what the defaults should be,
usually depending on the settings in the client registration that it holds.
NOTE: There is also a setting for `security.oauth2.client.client-authentication-scheme`
which defaults to "`header`" (but you might need to set it to "`form`" if, like Github for
instance, your OAuth2 provider doesn't like header authentication). In fact, the
`security.oauth2.client.*` properties are bound to an instance of
`AuthorizationCodeResourceDetails` so all its properties can be specified.
TIP: In a non-web application you can still create an `OAuth2RestOperations` and it
is still wired into the `security.oauth2.client.*` configuration. In this case it is a
"`client credentials token grant`" you will be asking for if you use it (and there is no
need to use `@EnableOAuth2Client` or `@EnableOAuth2Sso`). To prevent that infrastructure
to be defined, just remove the `security.oauth2.client.client-id` from your configuration
(or make it the empty string).
[[boot-features-security-oauth2-single-sign-on]]
==== Single Sign On
An OAuth2 Client can be used to fetch user details from the provider (if such features are
available) and then convert them into an `Authentication` token for Spring Security.
The Resource Server above support this via the `user-info-uri` property This is the basis
for a Single Sign On (SSO) protocol based on OAuth2, and Spring Boot makes it easy to
participate by providing an annotation `@EnableOAuth2Sso`. The Github client above can
protect all its resources and authenticate using the Github `/user/` endpoint, by adding
that annotation and declaring where to find the endpoint (in addition to the
`security.oauth2.client.*` configuration already listed above):
.application.yml
[source,yaml,indent=0]]
----
security:
oauth2:
...
resource:
userInfoUri: https://api.github.com/user
preferTokenInfo: false
----
Since all paths are secure by default, there is no "`home`" page that you can show to
unauthenticated users and invite them to login (by visiting the `/login` path, or the
path specified by `security.oauth2.sso.login-path`).
To customize the access rules or paths to protect, so you can add a "`home`" page for
instance, `@EnableOAuth2Sso` can be added to a `WebSecurityConfigurerAdapter` and the
annotation will cause it to be decorated and enhanced with the necessary pieces to get
the `/login` path working. For example, here we simply allow unauthenticated access
to the home page at "/" and keep the default for everything else:
[source,java,indent=0]
----
include::{code-examples}/web/security/UnauthenticatedAccessExample.java[tag=configuration]
----
[[boot-features-security-actuator]]
=== Actuator Security
If the Actuator is also in use, you will find: