5 changed files with 26 additions and 262 deletions
@ -1,137 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.client; |
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; |
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore; |
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionMessage; |
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionOutcome; |
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; |
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; |
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; |
|
||||||
import org.springframework.boot.autoconfigure.condition.SpringBootCondition; |
|
||||||
import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration; |
|
||||||
import org.springframework.boot.context.properties.bind.BindResult; |
|
||||||
import org.springframework.boot.context.properties.bind.Bindable; |
|
||||||
import org.springframework.boot.context.properties.bind.Binder; |
|
||||||
import org.springframework.context.annotation.Bean; |
|
||||||
import org.springframework.context.annotation.ConditionContext; |
|
||||||
import org.springframework.context.annotation.Conditional; |
|
||||||
import org.springframework.context.annotation.Configuration; |
|
||||||
import org.springframework.context.annotation.ConfigurationCondition; |
|
||||||
import org.springframework.core.env.ConfigurableEnvironment; |
|
||||||
import org.springframework.core.env.Environment; |
|
||||||
import org.springframework.core.env.MutablePropertySources; |
|
||||||
import org.springframework.core.env.PropertiesPropertySource; |
|
||||||
import org.springframework.core.io.ClassPathResource; |
|
||||||
import org.springframework.core.type.AnnotatedTypeMetadata; |
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration; |
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationProperties; |
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; |
|
||||||
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository; |
|
||||||
import org.springframework.util.CollectionUtils; |
|
||||||
|
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.List; |
|
||||||
import java.util.Map; |
|
||||||
import java.util.Properties; |
|
||||||
import java.util.Set; |
|
||||||
import java.util.stream.Collectors; |
|
||||||
|
|
||||||
/** |
|
||||||
* @author Joe Grandja |
|
||||||
*/ |
|
||||||
@Configuration |
|
||||||
@ConditionalOnWebApplication |
|
||||||
@ConditionalOnClass(ClientRegistrationRepository.class) |
|
||||||
@ConditionalOnMissingBean(ClientRegistrationRepository.class) |
|
||||||
@AutoConfigureBefore(SecurityAutoConfiguration.class) |
|
||||||
public class ClientRegistrationAutoConfiguration { |
|
||||||
private static final String CLIENTS_DEFAULTS_RESOURCE = "META-INF/oauth2-clients-defaults.yml"; |
|
||||||
static final String CLIENT_ID_PROPERTY = "client-id"; |
|
||||||
static final String REGISTRATIONS_PROPERTY_PREFIX = "security.oauth2.client.registrations"; |
|
||||||
|
|
||||||
@Configuration |
|
||||||
@Conditional(ClientPropertiesAvailableCondition.class) |
|
||||||
protected static class ClientRegistrationConfiguration { |
|
||||||
private final Environment environment; |
|
||||||
|
|
||||||
protected ClientRegistrationConfiguration(Environment environment) { |
|
||||||
this.environment = environment; |
|
||||||
} |
|
||||||
|
|
||||||
@Bean |
|
||||||
public ClientRegistrationRepository clientRegistrations() { |
|
||||||
MutablePropertySources propertySources = ((ConfigurableEnvironment) this.environment).getPropertySources(); |
|
||||||
Properties clientsDefaultProperties = this.getClientsDefaultProperties(); |
|
||||||
if (clientsDefaultProperties != null) { |
|
||||||
propertySources.addLast(new PropertiesPropertySource("oauth2ClientsDefaults", clientsDefaultProperties)); |
|
||||||
} |
|
||||||
Binder binder = Binder.get(this.environment); |
|
||||||
List<ClientRegistration> clientRegistrations = new ArrayList<>(); |
|
||||||
Set<String> registrationIds = getRegistrationIds(this.environment); |
|
||||||
for (String registrationId : registrationIds) { |
|
||||||
String fullRegistrationId = REGISTRATIONS_PROPERTY_PREFIX + "." + registrationId; |
|
||||||
if (!this.environment.containsProperty(fullRegistrationId + "." + CLIENT_ID_PROPERTY)) { |
|
||||||
continue; |
|
||||||
} |
|
||||||
ClientRegistrationProperties clientRegistrationProperties = binder.bind( |
|
||||||
fullRegistrationId, Bindable.of(ClientRegistrationProperties.class)).get(); |
|
||||||
clientRegistrationProperties.setRegistrationId(registrationId); |
|
||||||
ClientRegistration clientRegistration = new ClientRegistration.Builder(clientRegistrationProperties).build(); |
|
||||||
clientRegistrations.add(clientRegistration); |
|
||||||
} |
|
||||||
|
|
||||||
return new InMemoryClientRegistrationRepository(clientRegistrations); |
|
||||||
} |
|
||||||
|
|
||||||
private Properties getClientsDefaultProperties() { |
|
||||||
ClassPathResource clientsDefaultsResource = new ClassPathResource(CLIENTS_DEFAULTS_RESOURCE); |
|
||||||
if (!clientsDefaultsResource.exists()) { |
|
||||||
return null; |
|
||||||
} |
|
||||||
YamlPropertiesFactoryBean yamlPropertiesFactory = new YamlPropertiesFactoryBean(); |
|
||||||
yamlPropertiesFactory.setResources(clientsDefaultsResource); |
|
||||||
return yamlPropertiesFactory.getObject(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static Set<String> getRegistrationIds(Environment environment) { |
|
||||||
Binder binder = Binder.get(environment); |
|
||||||
BindResult<Map<String, Object>> result = binder.bind( |
|
||||||
REGISTRATIONS_PROPERTY_PREFIX, Bindable.mapOf(String.class, Object.class)); |
|
||||||
return result.get().keySet(); |
|
||||||
} |
|
||||||
|
|
||||||
private static class ClientPropertiesAvailableCondition extends SpringBootCondition implements ConfigurationCondition { |
|
||||||
|
|
||||||
@Override |
|
||||||
public ConfigurationCondition.ConfigurationPhase getConfigurationPhase() { |
|
||||||
return ConfigurationPhase.PARSE_CONFIGURATION; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { |
|
||||||
ConditionMessage.Builder message = ConditionMessage.forCondition("OAuth2 Client Properties"); |
|
||||||
Set<String> registrationIds = getRegistrationIds(context.getEnvironment()); |
|
||||||
if (!CollectionUtils.isEmpty(registrationIds)) { |
|
||||||
return ConditionOutcome.match(message.foundExactly("OAuth2 Client(s) -> " + |
|
||||||
registrationIds.stream().collect(Collectors.joining(", ")))); |
|
||||||
} |
|
||||||
return ConditionOutcome.noMatch(message.notAvailable("OAuth2 Client(s)")); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,58 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.client; |
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter; |
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore; |
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; |
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; |
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; |
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; |
|
||||||
import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration; |
|
||||||
import org.springframework.context.annotation.Configuration; |
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; |
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration; |
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; |
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; |
|
||||||
|
|
||||||
/** |
|
||||||
* @author Joe Grandja |
|
||||||
*/ |
|
||||||
@Configuration |
|
||||||
@ConditionalOnWebApplication |
|
||||||
@ConditionalOnClass(EnableWebSecurity.class) |
|
||||||
@ConditionalOnMissingBean(WebSecurityConfiguration.class) |
|
||||||
@ConditionalOnBean(ClientRegistrationRepository.class) |
|
||||||
@AutoConfigureBefore(SecurityAutoConfiguration.class) |
|
||||||
@AutoConfigureAfter(ClientRegistrationAutoConfiguration.class) |
|
||||||
public class OAuth2LoginAutoConfiguration { |
|
||||||
|
|
||||||
@EnableWebSecurity |
|
||||||
protected static class OAuth2LoginSecurityConfiguration extends WebSecurityConfigurerAdapter { |
|
||||||
|
|
||||||
// @formatter:off
|
|
||||||
@Override |
|
||||||
protected void configure(HttpSecurity http) throws Exception { |
|
||||||
http |
|
||||||
.authorizeRequests() |
|
||||||
.anyRequest().authenticated() |
|
||||||
.and() |
|
||||||
.oauth2Login(); |
|
||||||
} |
|
||||||
// @formatter:on
|
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,42 +0,0 @@ |
|||||||
security: |
|
||||||
oauth2: |
|
||||||
client: |
|
||||||
registrations: |
|
||||||
google: |
|
||||||
client-authentication-method: basic |
|
||||||
authorization-grant-type: authorization_code |
|
||||||
redirect-uri: "{baseUrl}/oauth2/authorize/code/{registrationId}" |
|
||||||
scope: openid, profile, email, address, phone |
|
||||||
authorization-uri: "https://accounts.google.com/o/oauth2/v2/auth" |
|
||||||
token-uri: "https://www.googleapis.com/oauth2/v4/token" |
|
||||||
user-info-uri: "https://www.googleapis.com/oauth2/v3/userinfo" |
|
||||||
user-name-attribute-name: "sub" |
|
||||||
jwk-set-uri: "https://www.googleapis.com/oauth2/v3/certs" |
|
||||||
client-name: Google |
|
||||||
github: |
|
||||||
client-authentication-method: basic |
|
||||||
authorization-grant-type: authorization_code |
|
||||||
redirect-uri: "{baseUrl}/oauth2/authorize/code/{registrationId}" |
|
||||||
scope: user |
|
||||||
authorization-uri: "https://github.com/login/oauth/authorize" |
|
||||||
token-uri: "https://github.com/login/oauth/access_token" |
|
||||||
user-info-uri: "https://api.github.com/user" |
|
||||||
user-name-attribute-name: "name" |
|
||||||
client-name: GitHub |
|
||||||
facebook: |
|
||||||
client-authentication-method: post |
|
||||||
authorization-grant-type: authorization_code |
|
||||||
redirect-uri: "{scheme}://{serverName}:{serverPort}{contextPath}/oauth2/authorize/code/{registrationId}" |
|
||||||
scope: public_profile, email |
|
||||||
authorization-uri: "https://www.facebook.com/v2.8/dialog/oauth" |
|
||||||
token-uri: "https://graph.facebook.com/v2.8/oauth/access_token" |
|
||||||
user-info-uri: "https://graph.facebook.com/me" |
|
||||||
user-name-attribute-name: "name" |
|
||||||
client-name: Facebook |
|
||||||
okta: |
|
||||||
client-authentication-method: basic |
|
||||||
authorization-grant-type: authorization_code |
|
||||||
redirect-uri: "{scheme}://{serverName}:{serverPort}{contextPath}/oauth2/authorize/code/{registrationId}" |
|
||||||
scope: openid, profile, email, address, phone |
|
||||||
client-name: Okta |
|
||||||
user-name-attribute-name: "sub" |
|
||||||
@ -1,4 +0,0 @@ |
|||||||
# Spring Boot Auto Configurations |
|
||||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ |
|
||||||
org.springframework.boot.autoconfigure.security.oauth2.client.ClientRegistrationAutoConfiguration,\ |
|
||||||
org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2LoginAutoConfiguration |
|
||||||
Loading…
Reference in new issue