1) Does GMail API work with free GMail or only with its paid GSuites version.
2) My .NET API client will be limited to sending a few emails a day to a small fixed set of addresses, the emails won't contain any sensitive personal data. Will it be easier for me to implement this with API keys or with OAuth 2?
Thank you .
Gmail API can be used with a regular Gmail account, no G Suite version needed. The API usage limits though, might vary depending on your account.
You have to use OAuth, as you can see here (API keys are usually used to access public resources, which is not the case):
Requests to the Gmail API must be authorized using OAuth 2.0 credentials.
Reference:
Implementing Server-Side Authorization
Related
I have seen this solved in popular platforms like Android & iOS using client SDKs. My question is
I have a RESTful server
I have a mobile client
How to
Create a signup which uses a federated OAuth (Google, FB, Microsoft etc) and use that to further authenticate the subsequent API calls.
This is what I am thinking
Client application calls the OAuth dialog of the login provider, and receives (after user consent), access token and user ID.
This is stored on the client and also passed to the server.
Server can validate (retreive) user info using the accessToken.
Sever can return IDtoken/Refreshtokens which client can use in subsequent API calls.
My question here is
Is this the right approach.
Can clients store the accesstoken (best practice?)
Can client pass the accessToken to backend (best practice?)
Is there an example, how this can be implemented for Google Auth (for a client and Webserver) without using SDKs.
The standard option is to implement the AppAuth pattern in your mobile app, meaning it signs in and uses tokens from your Authorization Server (AS). The mobile app then sends access tokens to your APIs.
Once this is done, signing in via Google, Facebook etc requires only config changes in the AS. Adding a new login / identity provider requires no code changes in either your UIs or APIs.
Here are Android and iOS samples of mine that use this approach and which you can run and maybe borrow some ideas from.
They use AWS Cognito as the AS - and I could configure Cognito to use Google or Facebook logins if I wanted to. Also I am in full control of scopes and claims added to access tokens - which my APIs can use to authorize requests.
ANSWERS
Almost right - your client app redirects to the AS and not Google / Facebook directly
Yes - mobile clients can store a refresh token in OS secure storage private to the app so that users do not need to login on every app restart. My samples do that.
Yes - mobile clients use access tokens as API message credentials
LIBRARIES
I agree with you here - avoid Google / Facebook libraries in your app. However it is recommended to use the respected AppAuth libraries - once integrated your app is compliant with any AS and will support all of its authentication flows.
Out of interest the AppAuth pattern even potentially enables future advanced scenarios such as App2App, since the AS can federate to an AS from another company (though I doubt that is relevant to you right now).
LEARNING CURVE
Finally it's worth mentioning that it is tricky to implement AppAuth - there are annoyances - but once done the architecture is in a good place.
Firstly, Any application that calls Google APIs needs to enable those APIs in the API Console.
Now, Any application that uses OAuth 2.0 to access Google APIs must have authorization credentials that identify the application to Google's OAuth 2.0 server.
For the credentials go to the Credentials Page and then fill the form according to your Application.
Note: Google recommends that you design your app's auth endpoints so that your application does not expose authorization codes to other resources on the page.
After getting your credentials, download the client_secret.json file from the API Console and securely store the file in a location that only your application can access.
For HTTP/REST, there is no need to install any libraries to call oAuth 2.0
Google's OAuth 2.0 endpoint is at https://accounts.google.com/o/oauth2/v2/auth. This endpoint is accessible only over HTTPS. Plain HTTP connections are refused.
As a client, the only thing you need to do for Basic authentication is to include an Authorization header in an HTTP request, composed of the username and password, separated by a colon and then Base64 encoded. E.g., in Ruby (1.9) using RestClient:
require 'restclient'
require 'base64'
auth = "Basic " + Base64::strict_encode64("#{username}:#{password}")
response = RestClient.get("https://myhost/resource",:authorization=>auth)
The token value is opaque to a client, but can be decoded by a Resource Server so it can check that the Client and User have permission to access the requested resource.
Authorization: Bearer <TOKEN_VALUE>
Send user to Google's OAuth 2.0 server. Example URL:
https://accounts.google.com/o/oauth2/v2/auth?
scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly&
access_type=offline&
include_granted_scopes=true&
state=state_parameter_passthrough_value&
redirect_uri=http%3A%2F%2Foauth2.example.com%2Fcallback&
response_type=code&
client_id=client_id
Request access token. Example:
POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded
code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
client_secret=your_client_secret&
redirect_uri=https://oauth2.example.com/code&
grant_type=authorization_code
Use API. Example:
GET /drive/v2/files HTTP/1.1
Authorization: Bearer <access_token>
Host: www.googleapis.com/
Is this the right approach.
Yes, pretty much. You're describing standard bearer token authorization. Access & ID tokens expire after a short time frame, and you have to use a long-lived refresh token to get new ones. The access token allows you to gain access, the refresh token is only useful for bootstrapping tokens.
Can clients store the accesstoken (best practice?)
Yes. You must store an OAuth refresh token. You may store the ID and access tokens (as opposed to keeping them in memory.)
On the web, you should not use Local Storage. Instead, use an httpOnly cookie.
On mobile, use platform features like Android's AccountManager or iOS' Keychain Services.
Can client pass the accessToken to backend (best practice?)
Yes, that's its purpose.
Is there an example, how this can be implemented for Google Auth (for a client and Webserver) without using SDKs.
I do not recommend this for several reasons. Firstly, your implementation will be less secure than Google's, who has a team devoted to ensuring their SDK is the most secure it can be. Secondly, you're not ready to try this implementation, yet. Start with the SDK, get it working, and then come back to this.
Using a solution like Auth0 will be the easiest way to start.
I have domain with aws example.com, currently I have record set so that when user goes to example.com, it serves static website from S3 (done with angular) and backend api (Lambda and API gate way). And I don't have sign in process, as the purpose of site is public facing.
I can use apikey on method to authorize the http call, but I still have to save it in js code somewhere, which I don;t want to do. And I am not sure how IAM role can help me in this scenario.
Is there any way I can let api allow calls from specific domain ?
You can use IAM Role defined for Unauthenticated user in AWS Cognito Federated Identities. The AWS document will guide through the process assigning IAM Role to the Unauthenticated user.
Then you can enable "AWS_IAM" Authorizer option in the API Gateway for any specific API's resources.
This question has similar approach in implementing the IAM Role - based to access API, in which the implementation is using External Federated Identities (Google) instead of unauthenticated user identities.
There are a few ways to skin this cat.
The least painful way is likely to be using AWS Signature V4-- unfortunately, there's no great answer for a site that doesn't have an auth system built in already. Someday they'll let us park API Gateways inside of VPCs, but that day isn't today.
I am currently working on a mobile application that will allow a user to sign in via username/password (OAuth 2.0 Password Grant), Facebook, Twitter, or Google. The backend for this mobile application is coded in Spring Boot/Cloud (Java) and makes use of Microservices principles. I have several small services that are discoverable via Eureka and make use of Spring Cloud Config for centralized configuration. They are all exposed to the Mobile device using Spring Cloud Zuul, which acts as a reverse proxy. The Spring Security OAuth 2.0 setup that I have takes in the username and password then returns a JWT token, this token is validated every time a request is made to the backend. I also store users locally in MongoDB and make use of Method Level Security. I want to add Social Login to my application and have it do the following:
On the Mobile Device do the OAuth dance and get an access token
Send the access token to the server, and using Spring Social create a new User locally and associate it to Facebook/Twitter/Google, and then return a JWT token that can be used to validate requests
This JWT token should be created by Spring Security, and I should still be able to use Method Level Security and have local users
Basically I want all the features I have with my custom Spring Security OAuth 2.0 Password Grant with Social Login
This is my first attempt in architecting a system, and therefore am looking forward to responses from those with much more experience than I have. I have seen many examples that use Spring Social, but all of them are for Web Apps, not for Mobile, this is where I am currently stuck at.
The questions I have are the following:
Is my suggested approach adequate? Are there other approaches that are stateless and better for mobile applications?
Is Spring Security OAuth 2.0 and Spring Social Security enough to accomplish this? If so, are there resources that I can use? I have not found many online.
Could Spring Cloud Security be used as a solution?
Should I consider using a 3rd Party provider for Authentication such as Auth0 or OKTA?
using OAuth2 for a stateless solution is in my opionion adequate, because of:
oauth2 in general is a protocol designed to be usable in every client, which is able to perform http requests. Since the social nets you mentioned all support OAuth2. If everything goes bad, you still can consume them manually respecting the oauth2 specs, which they implement.
in general I see a problem with "authenticate with XXX and use that token as JWT for my requests". This is not directly possible, because that token is for their resource servers. Instead you need to separate 2 processes: authentication and authorization. In short you can use the socials endpoints to authenticate a user in your backend, which leads to a second oauth2 generation from your authorization server. This can create a JWT using all features from spring-oauth.
This libary should used in addition, since it helps to setup a application wide security solution. As example, you keep an own authorizationserver (which authenticates using social login) and several resource servers. spring-cloud-security helps to build things on top of that, as Zuul SSO, hystrix+ribbon powered feign clients respecting oauth2 authentications and so on
I don't thing this will help you, because those services primary serve you as an identity provider, while you are going to couple your users identity over social networks
I hope I could clarify your question in some way
I have achieved it by referring two spring example applications. Check this
steps, you will be able to achieve social sso login with Zuul, Auth-server and multiple back-end REST projects.
I am successfully able to read my inbox content using Gmail API with desktop application.
But when I am trying to read other person gmail inbox, I am getting Delegation denied exception?
So my question here, will Gmail Api allow the applications to access other persons inbox or only the person who credentials are being used in generating Client_secret file??
Yes, it is possible to access others Gmail inbox. To access Gmail mailboxes, use Gmail API. Gmail API gives you flexible, RESTful acess to the user's inbox with a natural interface to Threads, Messages and History.
All you need to use the Gmail API is the client library for your choice of language and an app that can authenticate as a Gmail user. All requests to the Gmail API must be authorized by an authenticated user. You should use server-side flow when your application needs to access Google APIs on behalf of the user.
Here's a documentation how to implement Server-Side Authorization: https://developers.google.com/gmail/api/auth/web-server
This may be due to regulatory restrictions, I'm not sure why but it turns out that Google has not yet built any back-end support options for tracing Gmail messages within the Google Workspace administrator console
If your organization needs access to another user's Gmail account or tracks Gmail messages, I Highly Recommend using the Gmail Reader, it's a verified Google Workspace plugin, with a very user-friendly interface and a quick safe installation process directly from your Google Workspace Marketplace administrator console.
see the EZ Gmail Reader at Google Workspace Marketplace
I understand how the authorization process with Oauth works but is it somehow possible to authorize my access to my endpoints API without the user having to sign in? So what I'm trying to do is to restrict access to my API so that only certain websites, that I allow, have access to it and no others.
In Google APIs console I have created a 'client ID for web applications'.
In your described use case, the preferred solution is to use OAuth. In following the examples in the documentation, you'll be limiting the web sites (via the "JavaScript origins" value for the keys you obtained in the APIs Console).
Sites not listed in the origins will not be able to display the required authentication prompt (the client ID and origin are checked before Google will provide tokens). Developers will not be able to create their own client IDs with their preferred JavaScript origins, because your backend will be checking the client ID of the request is on a whitelist that is part of your code.