Ejemplo en Spring Boot 2.x
Spring Boot 2.x proporciona la capacidad de utilizar completamente la configuración automática para configurar el inicio de sesión a través de OAuth 2.0.
Esta sección muestra cómo configurar ejemplo de código para el inicio de sesión de OAuth 2.0, utilizando Google como proveedor de autenticación, y se tratan los siguientes temas:
Configuración inicial
Configurar el URI para la redirección
Configurar el archivo application.yml
-
Descargar la aplicación
Configuración inicial
Para utilizar el sistema de autenticación OAuth 2.0 de Google para iniciar sesión, debe configurar un proyecto en la consola API de Google para recibir OAuth 2.0. credenciales.
Siga las instrucciones en OpenID Connect, comenzando con la sección "Configurar OAuth 2.0".
Después de completar las instrucciones "Obtener credenciales de OAuth 2.0", se creará una nueva El cliente debe aparecer con las credenciales que consisten en un ID de cliente y un secreto de cliente.
Configuración de un URI de redireccionamiento
El URI de redireccionamiento es la ruta en la aplicación a la que se dirige el agente de usuario del usuario final. Se redirige después de autenticarse con Google y otorgar acceso al cliente OAuth (creado en el paso anterior) en la página de Consentimiento.
En la sección "Establecer URI de redireccionamiento", asegúrese de que el campo URI
de redireccionamiento autorizado esté configurado en localhost:8080/login
/oauth2/code/google
.
{baseUrl}/login/oauth2/code/{registrationId}
. RegistrationId es un identificador único para ClientRegistration
.
URI
admitidas para redirect-uri
.
Configure el archivo application.yml
Ahora que Si tiene uno nuevo cliente OAuth a través de Google, debe configurar su aplicación para utilizar un cliente OAuth para el flujo de autenticación. Para hacer esto:
Vaya a
application.yml
y establezca la siguiente configuración:spring: security: oauth2: client: registration: google: client-id: google-client-id client-secret: google-client-secret
Propiedades del cliente OAuthspring.security.oauth2.client.registration
es el prefijo de propiedad base para las propiedades del cliente OAuth.- El prefijo de propiedad base es seguido del identificador de
ClientRegistration
, por ejemplo google.
Reemplace los valores en
client-id
yclient-secret
a las credenciales de OAuth 2.0 que se crearon anteriormente.
Descargando la aplicación
Ejecute el ejemplo Spring Boot 2.x y vaya a localhost:8080
.
Luego será redirigido a una página de inicio de sesión estándar generada automáticamente que muestra un enlace para
Google.
Haga clic en el enlace de Google y será redirigido a Google para autenticarse.
Después de la autenticación Con las credenciales de su cuenta de Google, aparece la pantalla de Consentimiento en la página siguiente. La pantalla de Consentimiento le pedirá que permita o deniegue el acceso al cliente OAuth que se creó anteriormente. Haga clic en Permitir para permitir que el cliente de OAuth acceda a su dirección de correo electrónico y a la información básica de su perfil.
En este punto, el cliente de OAuth recibe su dirección de correo electrónico y su información básica de perfil. punto final UserInfo y establece una sesión autenticada.
Asignaciones de propiedades en Spring Boot 2.x
La siguiente tabla describe la asignación de las propiedades del cliente OAuth de Spring Boot 2.x a las propiedades
ClientRegistration
.
Spring Boot 2.x | ClientRegistration |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ClientRegistration
se puede configurar inicialmente usando punto final de configuración del proveedor de OpenID Connect o Punto final de metadatos del servidor
de autorización estableciendo la propiedad spring.security.oauth2.client.provider.[providerId].issuer-
uri
.
CommonOAuth2Provider
CommonOAuth2Provider
predefine un conjunto de
propiedades de cliente estándar para varios proveedores conocidos: Google, GitHub, Facebook y Okta.
Por ejemplo, authorization-uri
, token-uri
y
user-info-uri
no cambian frecuentemente para cualquier proveedor determinado. Por lo tanto, tiene
sentido proporcionar valores predeterminados para reducir la configuración requerida.
Como mostramos anteriormente cuando configuramos el cliente de Google, solo el client-id
y el las propiedades del cliente son obligatorias client-secret
.
El siguiente listado es un ejemplo:
spring:
security:
oauth2:
client:
registration:
google:
client-id: google-client-id
client-secret: google-client-secrett
registrationId
(google
) coincide con enum
GOOGLE
(no distingue entre mayúsculas y minúsculas) en CommonOAuth2Provider
.
En
los casos en los que necesite establecer un registrationId
diferente, por ejemplo
google-login
, aún puede utilizar la detección automática del valor predeterminado. propiedades del
cliente configurando la propiedad provider
.
El siguiente listado es un ejemplo:
spring:
security:
oauth2:
client:
registration:
google-login:
provider: google
client-id: google-client-id
client-secret: google-client-secre
- El
registrationId
está configurado engoogle-login
. - La propiedad
provider
está configurada engoogle
, lo que permitirá la detección de propiedades de cliente predeterminadas establecidas enCommonOAuth2Provider.GOOGLE.getBuilder()
.
Configuración de propiedades de proveedor personalizadas
Algunos proveedores de OAuth 2.0 admiten archivos compartidos arrendamiento, lo que da como resultado la creación de diferentes protocolos de puntos finales para cada inquilino (o subdominio).
Por ejemplo, un cliente OAuth registrado con Okta se asigna a un subdominio específico y tiene sus propios puntos finales de protocolo.
Para tales casos, Spring Boot 2 .x
proporciona la siguiente propiedad básica para configurar propiedades de proveedor personalizadas: spring.security.oauth2.client.provider.[providerId]
.
El siguiente listado es un ejemplo:
spring:
security:
oauth2:
client:
registration:
okta:
client-id: okta-client-id
client-secret: okta-client-secret
provider:
okta:
authorization-uri: https://your-subdomain.oktapreview.com/oauth2/v1/authorize
token-uri: https://your-subdomain.oktapreview.com/oauth2/v1/token
user-info-uri: https://your-subdomain.oktapreview.com/oauth2/v1/userinfo
user-name-attribute: sub
jwk-set-uri: https://your-subdomain.oktapreview.com/oauth2/v1/keys
- Propiedad base
(spring.security.oauth2.client.provider.okta
) le permite configurar de forma personalizada la ubicación de los puntos finales del protocolo.
Anulación de la configuración automática de Spring Boot 2.x
Clase de configuración automática Spring
Boot 2.x para soporte de cliente OAuth – OAuth2ClientAutoConfiguration
.
Realiza las siguientes tareas:
Registra
@Bean
paraClientRegistrationRepository
que consta de instanciasClientRegistration
de propiedades de cliente OAuth configuradas.Registra un
@Bean
paraSecurityFilterChain
y activa la autorización en OAuth 2.0 a través dehttpSecurity.oauth2Login()
.
Si necesita anular la configuración automática para necesidades específicas, puede hacerlo de las siguientes maneras:
Registrar @Bean para ClientRegistrationRepository
Registrar @Bean para SecurityFilterChain
Anulación completa de la configuración automática
Registro de @Bean para ClientRegistrationRepository
El siguiente ejemplo muestra cómo registrar
@Bean
para ClientRegistrationRepository
:
@Configuration
public class OAuth2LoginConfig {
@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
return new InMemoryClientRegistrationRepository(this.googleClientRegistration());
}
private ClientRegistration googleClientRegistration() {
return ClientRegistration.withRegistrationId("google")
.clientId("google-client-id")
.clientSecret("google-client-secret")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
.scope("openid", "profile", "email", "address", "phone")
.authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")
.tokenUri("https://www.googleapis.com/oauth2/v4/token")
.userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
.userNameAttributeName(IdTokenClaimNames.SUB)
.jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
.clientName("Google")
.build();
}
}
@Configuration
class OAuth2LoginConfig {
@Bean
fun clientRegistrationRepository(): ClientRegistrationRepository {
return InMemoryClientRegistrationRepository(googleClientRegistration())
}
private fun googleClientRegistration(): ClientRegistration {
return ClientRegistration.withRegistrationId("google")
.clientId("google-client-id")
.clientSecret("google-client-secret")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
.scope("openid", "profile", "email", "address", "phone")
.authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")
.tokenUri("https://www.googleapis.com/oauth2/v4/token")
.userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
.userNameAttributeName(IdTokenClaimNames.SUB)
.jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
.clientName("Google")
.build()
}
}
Registro de @Bean para SecurityFilterChain
El siguiente ejemplo muestra cómo registrar
@Bean
para SecurityFilterChain
usando la anotación @EnableWebSecurity
y
habilite la autorización en OAuth 2.0 a través de httpSecurity.oauth2Login()
:
@EnableWebSecurity
public class OAuth2LoginSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.oauth2Login(withDefaults());
return http.build();
}
}
@EnableWebSecurity
class OAuth2LoginSecurityConfig {
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
authorizeRequests {
authorize(anyRequest, authenticated)
}
oauth2Login { }
}
return http.build()
}
}
Anulación completa de la configuración automática
El siguiente ejemplo muestra cómo anular
completamente la configuración automática registrando @Bean
para
ClientRegistrationRepository
y @Bean
para SecurityFilterChain
.
@Configuration
public class OAuth2LoginConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.oauth2Login(withDefaults());
return http.build();
}
@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
return new InMemoryClientRegistrationRepository(this.googleClientRegistration());
}
private ClientRegistration googleClientRegistration() {
return ClientRegistration.withRegistrationId("google")
.clientId("google-client-id")
.clientSecret("google-client-secret")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
.scope("openid", "profile", "email", "address", "phone")
.authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")
.tokenUri("https://www.googleapis.com/oauth2/v4/token")
.userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
.userNameAttributeName(IdTokenClaimNames.SUB)
.jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
.clientName("Google")
.build();
}
}
@Configuration
class OAuth2LoginConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
authorizeRequests {
authorize(anyRequest, authenticated)
}
oauth2Login { }
}
return http.build()
}
@Bean
fun clientRegistrationRepository(): ClientRegistrationRepository {
return InMemoryClientRegistrationRepository(googleClientRegistration())
}
private fun googleClientRegistration(): ClientRegistration {
return ClientRegistration.withRegistrationId("google")
.clientId("google-client-id")
.clientSecret("google-client-secret")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
.scope("openid", "profile", "email", "address", "phone")
.authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")
.tokenUri("https://www.googleapis.com/oauth2/v4/token")
.userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
.userNameAttributeName(IdTokenClaimNames.SUB)
.jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
.clientName("Google")
.build()
}
}
Configuración basada en Java sin Spring Boot 2.x
Si no es posible usar Spring Boot 2.x, pero necesita configurar uno de los proveedores predefinidos en CommonOAuth2Provider
(por ejemplo, Google), aplique la siguiente configuración:
@EnableWebSecurity
public class OAuth2LoginConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.oauth2Login(withDefaults());
return http.build();
}
@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
return new InMemoryClientRegistrationRepository(this.googleClientRegistration());
}
@Bean
public OAuth2AuthorizedClientService authorizedClientService(
ClientRegistrationRepository clientRegistrationRepository) {
return new InMemoryOAuth2AuthorizedClientService(clientRegistrationRepository);
}
@Bean
public OAuth2AuthorizedClientRepository authorizedClientRepository(
OAuth2AuthorizedClientService authorizedClientService) {
return new AuthenticatedPrincipalOAuth2AuthorizedClientRepository(authorizedClientService);
}
private ClientRegistration googleClientRegistration() {
return CommonOAuth2Provider.GOOGLE.getBuilder("google")
.clientId("google-client-id")
.clientSecret("google-client-secret")
.build();
}
}
@EnableWebSecurity
open class OAuth2LoginConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
authorizeRequests {
authorize(anyRequest, authenticated)
}
oauth2Login { }
}
return http.build()
}
@Bean
open fun clientRegistrationRepository(): ClientRegistrationRepository {
return InMemoryClientRegistrationRepository(googleClientRegistration())
}
@Bean
open fun authorizedClientService(
clientRegistrationRepository: ClientRegistrationRepository?
): OAuth2AuthorizedClientService {
return InMemoryOAuth2AuthorizedClientService(clientRegistrationRepository)
}
@Bean
open fun authorizedClientRepository(
authorizedClientService: OAuth2AuthorizedClientService?
): OAuth2AuthorizedClientRepository {
return AuthenticatedPrincipalOAuth2AuthorizedClientRepository(authorizedClientService)
}
private fun googleClientRegistration(): ClientRegistration {
return CommonOAuth2Provider.GOOGLE.getBuilder("google")
.clientId("google-client-id")
.clientSecret("google-client-secret")
.build()
}
}
<http auto-config="true">
<intercept-url pattern="/**" access="authenticated"/>
<oauth2-login authorized-client-repository-ref="authorizedClientRepository"/>
</http>
<client-registrations>
<client-registration registration-id="google"
client-id="google-client-id"
client-secret="google-client-secret"
provider-id="google"/>
</client-registrations>
<b:bean id="authorizedClientService"
class="org.springframework.security.oauth2.client.InMemoryOAuth2AuthorizedClientService"
autowire="constructor"/>
<b:bean id="authorizedClientRepository"
class="org.springframework.security.oauth2.client.web.AuthenticatedPrincipalOAuth2AuthorizedClientRepository">
<b:constructor-arg ref="authorizedClientService"/>
</b:bean>