How do I use OAuth2AuthorizationCodeGrantFilter to associate an email address with its corresponding OAuth2AuthorizedClient? - spring

I have a Spring-based webapp that uses JavaMail to send and process mail via SMPT/IMAP.
I now need to add support for OAuth2 authentication, initially for GMail.
The webapp already uses Spring Security, so I've tried to integrate spring-security-oauth2-client 5.8.1
The objecive is:
user enters mail server details, and indicates that it should connect using OAuth2
on completion, a new browser window opens with a Spring Security URL e.g. http://localhost:8080/myapp/oauth/gmail
Spring Security redirects to Google to perform the authentication
Google redirects back to http://localhost:8080/myapp/oauth2/code/gmail
The access token and refresh token are received and stored, with the email address of the GMail account used as the principal
This works up to a point. In step 5, the OAuth2AuthorizationCodeGrantFilter uses securityContextHolderStrategy.getContext().getAuthentication() to get the principal prior to storing the token. In my case, this is the app user.
How can I make it the email address of the GMail user?
Is there a way to populate the OAuth2AuthorizationCodeGrantFilter with a different SecurityContextHolderStrategy via Spring-XML?
OAuth2AuthorizationCodeGrantFilter.processAuthorizationResponse():
...
Authentication currentAuthentication = this.securityContextHolderStrategy.getContext().getAuthentication();
String principalName = (currentAuthentication != null) ? currentAuthentication.getName() : "anonymousUser";
OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(
authenticationResult.getClientRegistration(), principalName, authenticationResult.getAccessToken(),
authenticationResult.getRefreshToken());
this.authorizedClientRepository.saveAuthorizedClient(authorizedClient, currentAuthentication, request,
response);
...

Related

What is the best way for implementing keycloak sso with existing spring-boot gateway service?

We're currently using jwt token based authentication in spring gateway service, where we generate token by providing username and passwords, then token is generated with required attributes.
Planning to integrate current login flow along with keycloak sso using IDP for this instance let's say azure-ad.
What would be better way to implement it, keeping the flow in sync with normal credential flow for generating JWT tokens at gateway?
As of now, We've tried the flow where user is sent to IDP's login screen, login event is captured on keycloak and sent to custom event handler (SPI), SPI fetches user attributes and generates token from project's user database and adds to keycloak specific db if it's not there.

How login works with REST API HTTPS (Spring)

So I'm a bit new with REST APIs and web in general. I'm trying to setup Login using HTTPS + Basic Auth through my REST API. My front end is built with Vuejs. Lets say there's a login button that sends the username and password information (basic auth by the way) what should the API return in the response? I was thinking it simply returns "Success"?
tl;dr how to perform login against a Spring Boot REST API using Vuejs through HTTPS + Basic Auth?
Thanks
For basic authentication you have to pass some key in headers to validate the user and then you can follow the crud to fetch that data of the user from database..since you are https you have to use keystore to authenticate the url also. It will return the role of the user on the basis of the role you can direct the user to that page , the user can be admin , normal user or user from diff department. you can also fetch active user (whether the user is active or not )

How to use Restcall with Spring Security

In my Spring MVC application I am using spring security. It works fine so far, but I have to admit, I do not understand all the details.
In the same application the user can call some controller functions by rest api. When the user (lets say Tom) does this, his authentication is lost. Instead the controller is called by user anonymous.
I tracked down that "user switch" to the code below. Variable restCall contains an url to my application. That call would work for user Tom, if he would place it in the browser directly. Using the restcall, the user changes to anyonymous.
1) Can I prevent that, when the calling User (Tom) was already logged in?
2) As those services should be called by a user that is not already browsing the web interface of the application, I would have to find a way to login by the rest call itself.
private void callWebservice(HttpServletRequest req, String restCall) {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response
= restTemplate.getForEntity(restCall, String.class);
logger.debug(response.toString());
//assertThat(response.getStatusCode(), equalTo(HttpStatus.OK));
}
You need, for example, a JSON Web Token (JWT) Authentication.
Steps are the following:
1) Client does an authentication, a post request with username and password
2) If authentication is successful, server returns a token in which is coded the user
3) In your next call, GET or POST, you add JWT to your header, this way the server will know who you are, because server can decode the token, and can grant also the right authorities and functionalities

Issue token to logged in user via spring

I have a Spring (3.2) based web app that a user can log into. The site will also provide an API secured via OAuth 2.0. My question then, is how do I go about generating a token for a logged in user?
The underlying idea here is that there will be a mobile app that opens up a web frame to the login page, which will eventually redirect to a url schema with an oauth token that the app will catch and then use for the api calls. Looking at the code for TokenEndpoint, I see that it defers token creation to a list of TokenGranter types. Should I be creating my own TokenGranter extended class, or am I looking at this all wrong?
I ended up writing a controller like this:
OAuthClientRequest request = OAuthClientRequest
.authorizationLocation(csOauthAuthorizeUrl)
.setClientId(csClientId)
.setRedirectURI(
UrlLocator.getBaseUrlBuilder().addSubpath(AUTH_CODE_HANDLER_URL).asUnEscapedString())
.setResponseType("code")
.buildQueryMessage();
UrlUtils.temporarilyRedirect(httpResponse, request.getLocationUri());
return null;
Then handling the code returned. My big problem here was that I had the /oauth/authorize endpoint set to use client credentials. Once I realized that tokens were being issued for the client ID instead of the user, it started to make sense.
So you want to use the Authorization Flow of OAuth. Spring has already support that, if you have configured the spring-security-oauth correctly, you just have to redirect the user/your mobile apps to /oauth/authorize?client_id=xxx&response_type=code this will redirect user to authorization page, if user has not login yet, it will redirect the user to login page then to the authorization page.
After the user completed the authorization process, it will redirect the user to an already registered redirect_url parameter with the authorization_code 'yourapp.com/callback?code=xxxx'.
Your application should exchange this authorization_code with the real token access to /oauth/token?grant_type=authorization_code&code=xxxx&client_id=xxxx&client_secret=xxxx
After that you will receive the token access that can be used to access the resource server.

Spring Security to Validate login RestAPI

I know this question asked many times but I did not get answer that I required.
I want link that can help me to create a spring security framework, In which I donot whant login form validation.
It should be done by login RestAPI. I just hit url like-
http://localhost:8080/login
post request containing username and password and it return json response with sucess or failure status
if sucess I would be able to hit secure API Requests.
I am using spring and spring security since 1 and half year with spring security to develop rest API I use below technique for user authentication
Follow below steps
Allow to access http:// localhost:8080/login for all user
User will pass username and password in body
Authenticate user with database entry
create access token and send back to response
using this access token user with interact with secure API.
I will provide source code if you need.
I suggest you to try with Basic Authentication. I believe Rest services are mutual contract between the consumer and provider, so re design your service to access the basic auth header. Your client need to pass the base64 encoded value of username:password, Your service should get the header value and decode you will get the original data back, Check against your backend storage (Ldap or DB).
More about basic authentication . BasicAuthentication

Resources