I have a Mobile application which uses oauth for authenticating users into the the app and getting/posting data to the API.
Currently I am using password grant types, which relies on a user entering their username & password. This is fine for carrying out tasks that the user needs to be authenticated for, however, the application itself needs to carry out duties that are not related to the application itself but only this application can be granted access.
What I therefore wondering - Is it possible to create a client which does not require a username/password in order to be given an access token so that the tasks (reading / writing) data can be done once authenticated? The access token can be granted for a long period of time and we are also implementing a way to refresh the token so the application can communicate with certain aspects of the API.
Related
I'm building an ASP.NET Core 6 MVC app and using the Microsoft.Identity.Web package for authentication and authorization.
How can my application acquire multiple scopes at once when a user from a new tenant logs in for the first time?
My app will be multi-tenant, and I want to acquire multiple scopes when a user from a new tenant logs in. I want to acquire the scopes up front (and not incrementally) because a frequent use case is that:
An admin user from a new tenant logs in and grants consent for the required scopes on behalf of their organisation
A non-admin user from the same tenant logs in afterwards. This user is not allowed to grant consent, and thus relies on the admin user to have granted consent up front.
I was initially using the [AuthorizeForScopes] attribute on my home controller to ensure that the relevant scopes were acquired. This works fine when acquiring a single scope at a time, but when I attempt to acquire multiple scopes at once it seems like the client (browser) goes into and endless loop. It's like it doesn't know which scope to ask for first.
I was expecting that my application would simply ask the user to grant consent to all the specified scopes at once.
Specifically I'm asking for these scopes:
https://graph.microsoft.com/v1.0/user.read
https://management.core.windows.net/user_impersonation
https://database.windows.net/user_impersonation
I have a web app which sends emails (gmail) in name of my users
When a user registers, she supplies gmail account and password. Also she has to enable access for Less Secure Apps (I recommend to create a new account for this)
Then I can open a gmail session
session = Session.getInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user.getEmail(), user.getPassword());
}
});
and send emails on her behalf.
Unfortunately this is going to stop working next 30th May, when Google will allow only OAUTH2 access
I have followed Java Quickstart for Gmail API and I have code up and running for sending emails with OAUTH2: enable gmail api, create an application on google cloud platform, grant send permission, oauth2 client id credential created...
The problem I have is I can't see a way to automatize this task because when creating an authorized credential, a consent screen displays on browser and you have to select the account to be granted manually (maybe because my app in google cloud platform is still pending to be reviewed)
Is there a way to infer the gmail account you want to access from the credentials file (client_secret.json)? Is there a way to automatize this?
No, or yes. It depends.
The whole point of OAuth2 is to improve security by working with authorization tokens rather than asking for user credentials. To do this the user has to consent to the app's access request, and thus the OAuth consent screen cannot be bypassed. This is
explained in Google's documentation. It's not related to your app's review status but rather it's the way OAuth works.
You can still work in a similar way, though . Instead of asking for username and password upon the user's registration you can redirect them to the OAuth consent screen so they can authorize your app. Make sure that your app is requesting offline access type and then you can retrieve an access_token and a refresh_token. These will essentially work as your credentials and you can use the refresh token to generate new access tokens when needed without having the user go through the consent screen each time.
The refresh token doesn't have a "natural" expiration so you can keep using it indefinitely, but there are a few scenarios where it will become invalid, such as it not being used for six months, the user changing passwords (if using Gmail scopes), the user manually revoking access, etc. In these cases you will need to direct them to the consent screen again to reauthorize your app.
In this sense, your app can still work automatically without user input except the initial setup, which you already had to deal with when they supplied you with their credentials. The refresh token expiration can even be compared to what you had to do when the users changed their passwords in your current workflow.
One exception to this are service accounts. If you and your users are part of a Google Workspace domain you can delegate domain-wide access to it, then the service account will be able to access user data without any manual input. Of course, this is because as the domain administrator you pretty much own all the accounts under it. But if you're working with a publicly available application you will have to deal with the limitations I mentioned above.
Sources:
Google's auth overview
Using OAuth 2.0 to access Google APIs
OAuth 2.0 for web applications
The OAuth consent screen
I've found plenty of information on implementing Oauth2 using a user authorization step, but I'm trying to run a container that automatically scrapes a gmail inbox for attachments transforms them, and exports to prometheus, and I'm having trouble figuring out how to implement this library: https://pkg.go.dev/golang.org/x/oauth2/clientcredentials#Config or any other for that matter to retrieve a token without involving a manual user step.
Will doing this in Go require writing direct API calls since I can't find an existing library to handle this scenario? Would it make more sense to create a Google App password and use generic user/pass SMTP authentication?
First off i understand what you are trying to do.
You have a backend system running in a container which will access a single gmail account and process the emails.
Now you need to understand the limitations of the API you are working with.
There are two types of authorization used to access private user data
service account - server to server interaction only works with workspace domains. No authorization popup required.
Oauth2 - authorize normal user gmail accounts, requires user interaction to authorize the consent screen
If you do not have a workspace account and this is a normal gmail user then you have no choice you must use Oauth2, which will require that a user authorize the application at least once.
Using Oauth2 you can request offline access and receive a refresh token which you can use to request new access tokens when ever you wish. The catch is that your application will need to be in production and verified, because your refresh token will only work for seven days and then it will expire. To fix this and get a refresh token that does not expire means that your application must in production and verified. This means you need to go though Googles verification process with a restricted gmail scope which requires third party security check and costs between 15k - 75k depending upon your application.
I understand that this is a single user system but that does not mean that you still need to go though verification. When google added the need for application verification they did not take into account single user systems like yours.
Option
Have you considered going directly though the SMPT server instead of using the Gmail api? If you use an apps password you should bypass everything by loging in using the login and the apps password.
I am developing and API (laravel passport) services and a first-party app (VueJs) to consume api.
Api will have a 2 parts
Public - means user do NOT need to be logged in to see a content
Private - means user do NEED to be logged in to see a content
Token for Public areas:
Since the application is developed by trusted source (same developers for api) I should be using a Client Credentials grant-type. However, since this is also a web-app, client credentials' confidentiality is not guaranteed.
So then I would need to use an Implicit grant type where a client_secret is not required. Then a user will have to authorize, which doesn't make much sense for a first-party app.
Token for Private areas:
It is obvious that I just need to use a Resource Owner Password Credentials grant type. Confusion come, as the client credentials will still be passed together with user credentials. And the client credentials can be used in public areas.
I am so very confused as which of the grant type(s) should be used in this case? Or is it fine to just use different grant types together?
I have 2 applications, the old application is using Oauth2 to access the Google Analytics API. All current users have granted access to an email from my domain.
The second application is using credentials with Service account authentication.
The problem is that the email for the Service account keys is using a different domain:
"client_email": "xxx-service#xxx.iam.gserviceaccount.com",
I need it to use my old email from my domain that already have permissions from clients.
How can I do that, I already downloaded the json file for the Service account keys.
There is a diffrence between Oauth2 and service accounts.
Lets start with the old app using Oauth2. When a user starts using the application they are displayed the authentication form which asks them to grant application X access to their data. Assuming they accept it application X can now read there data. Application X is given a Refresh token which can be used to access the data at a later date.
In the background the developer of Application X registered their application on Google Developer console and was given a client id and client secret. When the user authenticated to the application the Refresh token is created using the client id and client secret. You can not take a different client id and client secret and use it with the refresh token from another application they are not interchangeable.
Service accounts are different in that they are preauthorized. If you take that service account email address you have and add it as a user on the Google analytics website admin section. The service account will have access to read the information just like any other user.
Clarifications / answers.
You can not pick the service account email address these are generated by Google.
You can't use a service account to access data granted to an application though Oauth2. they are not interchangeable.
If you have access to the users data using Oauth2 you should be using your refresh tokens to access their data you do not need a service account.