How to integrate a regular username / password with a third-party social login for the Spring Boot + Angular web application?

I have an Angular + Spring bootable single page web application. The server also acts as an Auth server that issues tokens for an Angular application to use Restful API calls.

In my old login stream, request_type = password is used POST a call to the endpoint / oauth / token to get the carrier token. And all further API calls on behalf of the user will include the bearer token as the http authorization header.

Now I need to integrate the social login (facebook, twitter, etc.), which means that I do not have a username / password to create tokens, so I'm not sure how to make it work.

I used the following two tutorials as my template:

Spring Security and Angular JS

Spring Download and OAuth

In the first example oauth-vanilla example, a user proxy loads an authorization page. But I would like to have a traditional username and password login into the system (log in directly, rather than showing the login page).

In the second tutorial, after logging into facebook, I would like to use the facebook id to search my internal user database and create a new user, if that does not exist, and register him as a user. And use the internal user ID and authority to authorize future API calls on my API server.

I have a stripped-down pattern at https://github.com/dingquan/spring-angular-oauth

I can make POST calls to the / oauth / token endpoint and use the returned token for further api calls to my secure / api / blogs endpoint. But I do not know how to do the following:

  • The username / password in which the session cookie will be created, so I do not need to send an authorization token for future API calls to the resource endpoint

  • After logging into facebook (the login link for facebook is under the username / password input form), the calls to my endpoint are still not with error 401 (I have a "test" button that calls the / api / blogs call, you can click on it to see the behavior). So what am I missing to make the API call successful?

=== UPDATE ===

Just to clarify. Here are the goals I'm trying to achieve:

  • several authentication methods (traditional username / password, external user password, for example, facebook, possibly a mobile phone number + SMS code in the future).
  • we need our own user model supported by the database to store other user attributes, pure social input is not enough.
  • social login must be implicit. The user value should not be required to create a user account in our system manually after logging in through a third party (facebook, etc.). We do not just collect social user profile data to pre-fill out the registration form. We want to automatically create new database users behind the scenes if none of the existing db users is associated with this external social account. that is, if the user is logged in via facebook, they do not need to enter a username / password. Authentication via facebook will automatically register the user in our system, and the user should have access to limited resources after logging in to facebook.

There is some kind of confusion that I can ask people to put their username / password on facebook in the login form posted in my application, and I will login to facebook on behalf of the user. This is not what I asked for.

+5
source share
1 answer

You do not need such a complicated configuration. Add @EnableOAuth2Sso to your MainConfiguration and set the appropriate application properties.

Here is what I did to use Facebook as an authorization server.

a) Remove clientId and authServer from UserServiceImpl . Otherwise, you will have to configure an authorization server, which is not needed.

b) Remove AuthorizationServerConfiguration .

c) Add @EnableWebSecurity and @EnableOAuth2Sso to MainConfiguration .

d) Change MainConfiguration::configure to

 http .logout().logoutSuccessUrl("/").permitAll().and() .authorizeRequests().antMatchers("/", "/login", "/home.html").permitAll() .anyRequest().authenticated() .and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); 

e) Remove everything else except the nested AuthenticationSecurity class from MainConfiguration .

f) Change ResourceServerConfiguration::configure(HttpSecurity) to

 http.antMatcher("/api/**").authorizeRequests().anyRequest().authenticated(); 

f) Remove the tokenStore attribute and the ResourceServerConfiguration::configure(ResourceServerSecurityConfigurer) method from the ResourceServerConfiguration .

g) Remove the security and facebook configuration block from application.yml . Add this one instead

 security: oauth2: client: client-id: <CLIENT_ID> token-name: oauth_token authentication-scheme: query client-authentication-scheme: form access-token-uri: https://graph.facebook.com/oauth/access_token user-authorization-uri: https://www.facebook.com/dialog/oauth resource: user-info-uri: https://graph.facebook.com/me client-id: <CLIENT_ID> client-secret: <CLIENT_SECRET> token-type: code 

h) In index.html change <a href="#/login">login</a> to <a href="/login">login</a> . i) Replace the contents of hello.js with one .

But I would like to have a traditional username and password login (log in directly, rather than showing the login page).

I would never use a site that requires my credentials without redirecting me to the source! I don’t know you, and you are considered a phishing site under suspicion. You must really reconsider your decision.

Btw, I created a migration request with these changes.

+5
source

Source: https://habr.com/ru/post/1257905/


All Articles