skip to Main Content

I am working on a Spring boot web application. I have now working a registration and login system using Spring Security with a custom userDetailService.

Now I want add a register-login system using Google Accounts. I created my Google API keys and added them to the application.properties. I think is not necessary use .yml propertie files here:

# ===============================
# = OAUTH2
# ===============================
security.oauth2.client.client-id=clientId Here
security.oauth2.client.client-secret=clientSecret here
security.oauth2.client.access-token-uri=https://www.googleapis.com/oauth2/v3/token
security.oauth2.client.user-authorization-uri=https://accounts.google.com/o/oauth2/auth
security.oauth2.client.token-name=oauth_token
security.oauth2.client.authentication-scheme=query
security.oauth2.client.client-authentication-scheme=form
security.oauth2.client.scope=profile
security.oauth2.resource.user-info-uri=https://www.googleapis.com/userinfo/v2/me
security.oauth2.resource.prefer-token-info=false

I added OAuth2 support to my Spring Boot application on this way:

@SpringBootApplication
@EnableOAuth2Sso
public class WebApplication {

    public static void main(String[] args) {
        SpringApplication.run(WebApplication.class, args);
    }
}

Now I want keep the posibility to login using Google or login using a website account, but I only found manuals about unique login or multiple providers login (Facebook, Google, Twitter..)

In my SpringSecurity configuration class I have this. I think that I have to create a authenticationProvider for Google and link it to the google access url in my app, but I am so confused yet about this:

    @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

            /**
             * Obtenemos información de persistencia
             */
            // @formatter:off
            auth
                //.authenticationProvider(googleOauth2AuthProvider())
                .userDetailsService(userDetailsService)
                .passwordEncoder(bCryptPasswordEncoder);
            // @formatter:on
    }
    ...
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        String[] anonymousRequest = { urls};

        http
        .authorizeRequests()
        //..other rules

2

Answers


  1. You can achieve this using Spring Social or OAUTH2

    If you want to do using spring social be aware that Google is not supported by default in spring boot social so you have to do a couple of extra steps.

    1. Add Maven Dependencies

      <dependency>
          <groupId>org.springframework.social</groupId>
          <artifactId>spring-social-google</artifactId>
          <version>1.0.0.RELEASE</version>
      </dependency>
      
    2. Add a GoogleAutoConfiguration Class

    Do Ctrl+Shift+T in your IDE(eclipse) and look for FacebookAutoConfiguration class you should be able to find it either in org.springframework.boot.autoconfigure.social package in spring-autoconfigure.jar. Copy this File and replace Facebook with Google.

    3.Add GoogleProperties

    In the same package add the below class

    @ConfigurationProperties(prefix = "spring.social.google")
    
    public class GoogleProperties extends SocialProperties{
    

    Update the application.properties with your google API key

    Follow this link for complete description and step by step instruction

    Hope It helps !!

    If you want to do using OAUTH2 here is a working example

    Login or Signup to reply.
  2. You have to use a composite filter in which you configure your desired authentication providers, for example:

    private Filter ssoFilter() {
        CompositeFilter filter = new CompositeFilter();
        List<Filter> filters = new ArrayList<>();
        filters.add(ssoFilter(facebook(), "/login/facebook"));
        filters.add(ssoFilter(google(), "/login/google"));
        filter.setFilters(filters);
        return filter;
    }
    
    private Filter ssoFilter(ClientResources client, String path) {
        OAuth2ClientAuthenticationProcessingFilter oAuth2ClientAuthenticationFilter = new OAuth2ClientAuthenticationProcessingFilter(
                path);
        OAuth2RestTemplate oAuth2RestTemplate = new OAuth2RestTemplate(client.getClient(), oauth2ClientContext);
    
        oAuth2ClientAuthenticationFilter.setRestTemplate(oAuth2RestTemplate);
        UserInfoTokenServices tokenServices = new UserInfoTokenServices(client.getResource().getUserInfoUri(),
                client.getClient().getClientId());
    
        tokenServices.setRestTemplate(oAuth2RestTemplate);
        oAuth2ClientAuthenticationFilter.setTokenServices(tokenServices);
        return oAuth2ClientAuthenticationFilter;
    }
    

    where:

    @Bean
    @ConfigurationProperties("google")
    public ClientResources google() {
        return new ClientResources();
    }
    
    @Bean
    @ConfigurationProperties("facebook")
    public ClientResources facebook() {
        return new ClientResources();
    }
    

    and:

    class ClientResources {
    
        @NestedConfigurationProperty
        private AuthorizationCodeResourceDetails client = new AuthorizationCodeResourceDetails();
    
    
        @NestedConfigurationProperty
        private ResourceServerProperties resource = new ResourceServerProperties();
    
        public AuthorizationCodeResourceDetails getClient() {
            return client;
        }
    
        public ResourceServerProperties getResource() {
            return resource;
        }
    }
    

    finally, add the filter before the BasicAuthenticationFilter in your HTTP security config:

    @Override
        protected void configure(HttpSecurity http) throws Exception {
            String[] anonymousRequest = { urls};
    
            http
            .authorizeRequests()
            //..other rules
            addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
    

    Ps: your configuration properties has to start with the value specified in the @ConfigurationProperties("facebook"):

    facebook:
      client:
        clientId: yourCliendId
        clientSecret: yourClientSecret
        accessTokenUri: https://graph.facebook.com/oauth/access_token
        userAuthorizationUri: https://www.facebook.com/dialog/oauth
        tokenName: oauth_token
        authenticationScheme: query
        registeredRedirectUri: http://localhost:8083/app.html
        preEstablishedRedirectUri: http://localhost:8083/app.html
        clientAuthenticationScheme: form
      resource:
        userInfoUri: https://graph.facebook.com/me
    

    This is inspired from the example presented here: https://github.com/spring-guides/tut-spring-boot-oauth2/tree/master/github

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search