I am implementing a spring boot application that needs to provide OAuth2 token authorization and support multiple social services (google+, facebook etc). The user should be able to select his preferred social network and sign-in using the OAuth2 authorization framework. I am implementing the above using the approach described here http://cloud.spring.io/spring-cloud-security/.
Currently my application.yml looks like this
spring:
oauth2:
client:
clientId: {{my app's google id}
clientSecret: {{my app's google secret code}}
etc...
Also, the spring boot main class is annotated as @EnableOAuth2Sso.
My problem is that with the above approach I can only use one social network for my purposes (google+ in the example). So, I would like to know if there is a way to support, simultaneously, multiple social networks by defining them somehow in the .yml file. Is this possible or should I use another approach?
thanks for your time,
Chris
The @EnableOAuth2Sso
feature wasn't designed to support multiple providers as simple YAML declarations. Instead of using that you need to install 2 separate OAuth2AuthenticationProcessingFilters
in your security configuration, each with a different login path, and then link to them from a UI.
Indeed, please check the link posted by Mario (not sure why it was downvoted..): social_login_manual
The link says that @EnableOAuth2Sso is essentially a combination of @EnableOAuth2Client and some additional magic. The downside is you can't easily customize its behavior to support multiple providers. Thus in the tutorial it is suggested to replace it with @EnableOAuth2Client instead and go by repeating what @EnableOAuth2Sso does under the hood with some custom additions.
So, here is how it looks like:
@SpringBootApplication
@EnableOAuth2Client
@RestController
public class SocialApplication extends WebSecurityConfigurerAdapter {
private Filter ssoFilter() {
CompositeFilter filter = new CompositeFilter();
List<Filter> filters = new ArrayList<>();
filters.add(ssoFilter(facebook(), "/login/facebook"));
filters.add(ssoFilter(github(), "/login/github"));
filter.setFilters(filters);
return filter;
}
private Filter ssoFilter(ClientResources client, String path) {
OAuth2ClientAuthenticationProcessingFilter filter = new OAuth2ClientAuthenticationProcessingFilter(path);
OAuth2RestTemplate template = new OAuth2RestTemplate(client.getClient(), oauth2ClientContext);
filter.setRestTemplate(template);
filter.setTokenServices(new UserInfoTokenServices(
client.getResource().getUserInfoUri(), client.getClient().getClientId()));
return filter;
}
@Bean
@ConfigurationProperties("github")
public ClientResources github() {
return new ClientResources();
}
@Bean
@ConfigurationProperties("facebook")
public ClientResources facebook() {
return new ClientResources();
}
}
class ClientResources {
@NestedConfigurationProperty
private AuthorizationCodeResourceDetails client = new AuthorizationCodeResourceDetails();
@NestedConfigurationProperty
private ResourceServerProperties resource = new ResourceServerProperties();
public AuthorizationCodeResourceDetails getClient() {
return client;
}
public ResourceServerProperties getResource() {
return resource;
}
}
facebook:
client:
clientId: 233668646673605
clientSecret: 33b17e044ee6a4fa383f46ec6e28ea1d
accessTokenUri: https://graph.facebook.com/oauth/access_token
userAuthorizationUri: https://www.facebook.com/dialog/oauth
tokenName: oauth_token
authenticationScheme: query
clientAuthenticationScheme: form
resource:
userInfoUri: https://graph.facebook.com/me
github:
client:
clientId: bd1c0a783ccdd1c9b9e4
clientSecret: 1a9030fbca47a5b2c28e92f19050bb77824b5ad1
accessTokenUri: https://github.com/login/oauth/access_token
userAuthorizationUri: https://github.com/login/oauth/authorize
clientAuthenticationScheme: form
resource:
userInfoUri: https://api.github.com/user
I also stumbled upon this and many other questions about multiple authentication provider support. Syer's answer that core @EnableOAuth2Sso
annotation wasn't designed for this was actually very helpful. It made me look elsewhere.
Benefiting from Nimbus OAuth library I designed another approach. It probably isn't clean and nice, but it does what I was planning. Separate authentication providers are defined in properties and selected based on URI path.
This is what I came up with: https://bitbucket.org/klaalo/orcidconnect/src/f3e4fada9827e47bd33efd579fd020c41e37ee2a/src/main/java/fi/csc/orcidconnect/oauth2client/
Basically, a provider is selected based on a decision made by DelegatingAuthenticationProviderEndpoint
in SecurityConfiguration (on default package). AuthenticationProcessingFilter
is waiting for authentication events and making redirects to authentication providers. On return it will validate received code and carries AuthenticationToken
for custom AuthenticationProvider
to evaluate.
Received UserDetails are persisted to User object in a Map.
Hope this helps.
The link you have provided only shows how to use the @EnableOAuth2Sso facilities that enables a single Authentication Server provider. In order to implement multiple providers you should follow :
https://spring.io/guides/tutorials/spring-boot-oauth2/#_social_login_manual
and implement a filter for each provider.
来源:https://stackoverflow.com/questions/33512401/enableoauth2sso-simultaneously-for-multiple-social-networks