Authenticating a user using Google - java

I'm having a hard time wrapping my head around how to authenticate a user in my REST service. I plan to use Google Sign-in (on Android, namely). I can't quite figure out how to authenticate users on my server. I do not want to have any authorizations (other than validating the identity of the user), all I want to do is when I receive a request, validate that the user is who he (or she) says he is.
My understanding is that the user will login, get some sort of token from Google, then send that token along his request to my server which I will use to validate his identity. However, from what I read, the user will encode their requests in a JWT (json web token), which I will then use to validate their identity without ever talking to the Google server directly. Did I understand properly?
On Google's documentation, it says
If you do not require offline access, you can retrieve the access token and send it to your server over a secure connection. You can obtain the access token directly using GoogleAuthUtil.getToken() by specifying the scopes without your server's OAuth 2.0 client ID.
But it does not say what the server should do with the token.

You have an android app which enables user to log in via Google+ Sign-In, and then this Android app will call your REST API. What you want is how your service authenticates this request. This Android client will send request to your service with token, and you need to validate this token for authentication. Is my understanding right?
If so, you need to validate the token sent to your service. The reference you mentioned is for Google API calls, in your case; it's your own service API call. For the Android side, just follow the reference, in your service side you can use TokenInfo validation to authenticate users.

Related

Google Cloud OAuth 2.0 Request Token without user interaction - Java

I am working on a solution to read log files from the GCP for an internal process. However, i am having a difficult time trying to generate an Auth Token for the request to grab the logs needed. This is more of a flow\context question rather than a whats wrong with my code one
The key issues i am having is that i do not want to prompt for web-browser authentication. I want to be able to do this all through API request and have no user interaction. Everywhere i have looked and all implementations i have tried, i am prompt for user interaction in some way and that is just not feasible for this solution.
How can this be achieved?
We do not have IAM enabled, so i cannot generate a JWT token.
I am trying to do this through using a Service Account created using client id and client secret.
I have tried getting a "code" to pass into a request to generate an authorization token, but that has been prompting me for user authorization in the browser which will not work, even when I add the query parameter 'prompt' or 'approval_prompt' to none or force.
I feel like i am missing one crucial piece to be able to achieve this flow and any help/guidance will be greatly appreciated.
There are several ways to authenticate API calls. If you want to do it without user interaction, you will need to use a Service Account (more info here). The process would be the following:
You use the client ID and one private key to create a signed JWT and construct an access-token request in the appropriate format. Your application then sends the token request to the Google OAuth 2.0 Authorization Server, which returns an access token. The application uses the token to access a Google API. When the token expires, the application repeats the process.
For this, you can use Client Libraries or you can do it manually with HTTP requests directly. In the docs there is a guide to do so.

Mobile authentication using QR in web application

I have doubts about what the correct schema should be for the next technical solution.
I need to authenticate a user in a mobile application by reading a QR code, the user being previously authenticated in a web application.
The use case consists in that the user uses a web application located in an intranet, but needs to be able to upload images from a mobile device that will be connected to the internet.
The mobile application will consume a public API exposed on the internet through a API Gateway.
The API Gateway will connect to the backend to upload the images.
As a requirement, when the user needs to use the mobile device to capture and upload images, they should not authenticate again, since they have an open session in the web application, and simply use a QR code to authenticate the device. Logically the QR will not use the user's credentials.
My idea is to make use of Oauth 2.0 with the following flow to authenticate mobile device:
The web application requests API Gateway to generate an authorization token and it responds with a UUID.
The web application will display the authorization token using a QR received from the API Gateway.
The mobile device will read the QR, and request an access token to the API Gateway with the authorization token.
The API Gateway validates the authorization token and generates the access token that is returned to the mobile device.
The mobile device makes calls to the public API (API Gateway) using the access token.
My question is whether it is the correct scheme, or there is another standard solution.
Thanks!!
Your scheme will work BUT it's not reaching its fullest security potential considering the fact that you can transfer a new generated authorization token from an already authorized device directly to another one(via QR code read by camera); this fact would make step 3 and 4 an unnecessary vulnerability(it's also a redundancy,there already is a token!, why get another one?);
The following alternative along with good cryptography can make the later authorized device connection almost impossible to intrude.the idea is that by adding a symmetric encryption layer before sending the data in step 5 and using a key which is exchanged over another medium(the already authorized device and server) the encrypted data can never be exposed;
step 3 replacement: read the authorization token;
step 4 replacement: check the secure hash derivation of the authorization token(instead of the token itself) with the server to see if its valid;
token0=read_auth_token_from_camera()
public_token=hash_function(token0) //the useless exposed token
if(check_token_with_server_for_authenticity(public_token)==true)
continue_to_step_5() //it's authorized
else
handle_the_scenario()
step 5 replacement: encrypt your request and authorization token with another hash derivation of the authorization token then make calls to the server API;
token2=another_hash_function(token0)
request="i am top secret data"
encryption_key=token0
encrypted_request=encryption_function( token2 + request , encryption_key)
send_to_server( public_token+encrypted_request)
//notice that token2 is unknown to the intruder because its encrypted,but it is known to the server; hence the authenticity of each request can be checked by the server;
how it is more secure: in this alternative way the actual authorization token is never really exchanged between the server and the new client; So if an intruder could hypothetically break the SSl/TLS layer and capture the public token, the intruder won't be able to send any requests on your behalf or modify the data in requests;
If this scheme fulfills your desired application flow then its correct. Their is no standard way to authenticate android devices if you are going for self-made authentication.
One thing that I think you need to add is a check whether the client is actually your android application and not any other application using similar authentication flow. If you can cater this than its good to go.
You can use FireBase ML Kit for a good solution and it can also performs a lot AI-based functions to your apps.
You can check it from here:
https://firebase.google.com

Secure REST endpoints with service user or public user

I'm writing a mobile app that communicates to a remote Java service via REST. I have protected my (SpringBoot) web service with https protection (due to the nature of the data, it needs to be secure) but my question is about which user/password I use to secure the https calls.
Should the username and password I use in the https header be a service account that the client (mobile app) and Java service knows or should it be the public user's username and password? The easiest option is just to use a service account but this means the mobile app will have those details built into it and distributed publically (albeit in compiled form).
Going the other way and using the user's username and password means I'll have to have the logon REST endpoint open and unsecure (which is fine I guess), but it just makes it slightly more fiddly.
Good question, and I would reckon you to use token based authentication and authorization scheme. Firstly you should have a login page where client logs in by providing username and password which is authenticated by calling some remote login service which maintains it's own user store or may use an existing one in your organization if any. Upon a successful authentication, the auth service should provide the client with a valid token, which then be refreshed time to time. The mobile or web client should pass in the token to the downstream microservices when a request is sent and this token should be sent inside the Authorization HTTP header.
Exposing the username and password while passing it around the network normally not considered as a good solution and that's where token becomes handy too. Token is the normal procedure that people use to secure rest endpoints. Yous rest endpoint should intercept each and every request comes at it, passes the token to the auth provider and verifies that. If the token is valid it will allow the request otherwise it should deny it.
Security is a pretty much larger topic and you have X.509 certificates other than tokens to encrypt the data sent across the wire over https and so forth. I suggest you to take a look at the spring security documentation since that will be a good starting point. Spring Security gives lots of hooks for developers which can be used out of the box with some sensible defaults. You can use JWT style tokens, Oauth tokens and spring security supports all these different forms too.

How should I create a new Federated Identity Provider for Firebase Authentication

I would like to integrate PayPal signin into an android app so to authenticate the client to the Firebase Database. I've managed to create a custom funtion on the node.js server that creates tokens from the provided uid, in order to use "signin withcustomtoken" function in the client application. Should I send the uid to the nodejs server through https in order to get the token? Is there a better way?
Don't create an HTTP endpoint that accepts a uid and returns a custom token. This is a huge security vulnerability as any attacker would be able to impersonate any user knowing their uid.
What you need to do is the following:
Implement a paypal OAuth code flow. You can use third party libraries for that.
When you get the paypal OAuth authorization code, you send it to your backend, you use the paypal client ID and secret to exchange for a paypal refresh token and access token. You can then get the user info associated with that paypal user including their paypal uid. You would then mint a Firebase custom token using the Firebase Admin SDKs and return it to the client.
On the client you would signInWithCustomToken to complete sign in with that custom token.
In this case you are exposing an HTTP endpoint that takes an authorization code and returns a Firebase custom token.
This is the basic idea (details excluded). Of course you still have to ensure the flow starts and ends on the same device by passing some state and then check that you get it back in the end. You also have to ensure the auth code is returned to the correct app using something like app links, etc. Firebase Dynamic Links can be helpful there.

How to access Graph API from a Web API with ADAL JS issued implicit grant token

I have a Web API built in Java that returns database information to an SPA. I need to check the user's group information using AAD Graph API before delivering the response. Right now the Web API accepts the request and reads the user's token (eyJ...).
What are the next steps for the application to be ready to send a request to Graph API on behalf of the user?
I have tried sending the request with the Authorization: Bearer ey... header using the user's token but receive a Authentication_MissingOrMalformed error. I have also tried various edits to the app manifest and delegated permissions with no luck.
The access token that your API received is intended only for your API. What you need is to obtain a new access token, on behalf of the current user, for the Azure AD Graph API.
Fortunately, this is exactly what the on-behalf-of flow is for. From Authentication Scenarios for Azure AD:
Delegated User Identity with OAuth 2.0 On-Behalf-Of Draft Specification
The flow discussed below assumes that a user has been authenticated on another application (such as a native application), and their user identity has been used to acquire an access token to the first-tier web API.
The native application sends the access token to the first-tier web API.
The first-tier web API sends a request to Azure AD’s token endpoint, providing its client ID and credentials, as well as the user’s access token. In addition, the request is sent with an on_behalf_of parameter that indicates the web API is requesting new tokens to call a downstream web API on behalf of the original user.
Azure AD verifies that the first-tier web API has permissions to access the second-tier web API and validates the request, returning a JWT access token and a JWT refresh token to the first-tier web API.
Over HTTPS, the first-tier web API then calls the second-tier web API by appending the token string in the Authorization header in the request. The first-tier web API can continue to call the second-tier web API as long as the access token and refresh tokens are valid.
Be sure to configure your API to request the right set of permissions for the Azure AD Graph API.
Edit: If you are constructing the token request yourself, the request that your API would make to Azure AD to get a new token to the Graph API on behalf of the current user would be a POST against:
https://login.microsoftonline.com/{tenant-id}/oauth2/token
With the following parameters in the body (un-encoded, for readability, in reality these would be application/x-www-form-urlencoded, of course):
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&
requested_token_use=on_behalf_of&
assertion={access-token}&
client_id={api-client-id}&
client_secret={api-client-secret}&
resource=https://graph.windows.net&
scope=openid
Where {tenant-id} is the directory identifier (domain name or Guid value), {access-token} is the access token that your SPA provided to your API (the one you're exchanging for an access token to the Graph API), {api-client-id} is the client ID for your API, and {api-client-secret} is the API's secret password credential.
(Note, for simplicity, this example uses password credentials (client_secret) to authenticate the API, though it could very well be using instead an assertion signed by a client certificate.)

Categories