I have successfully sent emails in my application using OAuth 1.0a (using Signpost) by constructing an XOAUTH string as described here. The problem is that access tokens expire after an hour and this XOAUTH won't authenticate the user for SMTP server after that.
Is there a way to extend/refresh the access token's lifetime without user's intervention? I know this Android app does that, but how?
I managed to upgrade to OAuth 2.0 (using Scribe) where I'm given a refresh token as well, but it looks like Gmail XOAUTH doesn't support OAuth 2.0 tokens. Does Google provide another way to send emails?
I just managed to fix it.
The OAuth 1.0 access token is actually long-lived, but the XOAUTH string is valid for a short period of time, hence needs to be created/signed frequently.
Related
I am writing a service that will access a Google Nest Thermostat, and need a Google Oauth2 token in order to do so. All of the documentation I can find references a browser-driven login to identify, authenticate, and then store a token as a cookie.
All of my OAuth experience has involved receiving a secret and/or API key, and then using that against a token service to get a security token. I then use that token for subsequent API endpoints. All of the Google docs / samples tell me I have to get my "headless" service to log in via browser and get a token via a redirect, the same way I'd log in to any other service using my Google credentials. Is there a way to do this without a live browser session, i.e. just a Google endpoint that I trigger with my secret data, to get a token to use with the Google Smart Home APIs?
I would like to authenticate against KeyCloak using "Direct Access Grant": https://www.keycloak.org/docs/latest/server_admin/index.html#resource-owner-password-credentials-grant-direct-access-grants
I works like a charm when keycloak manages users and passwords on its own.
But, my scenario is different:
I would like keycloak to act a Broker to some external IDP. KeyCloak has identity brokering feature - but in only works in "Authorization Code flow" - redirecting user to external IDP login form.
I have mobile app and would like ot use "direct access grant" - so that app comunicates with keycloak to authenticate user - and keycloak, as a broker, authenticates this user (using openid-connect) in external IDP
How to achieve such scenario ? I know that it is not possible out of the box - but maybe somebody could advice how write an extension to keycloak do make this scenario possible ?
Whatever it is you are trying to achieve this way, it goes directly against what OAuth and OpenID Connect were designed for. The whole idea of using access tokens is to allow some relying party (such as a mobile app) to interact with a service on behalf of the user without ever getting to see the user's credentials (like a password).
Think of it like this. Let's say you have some app on your mobile phone. It can make use of certain services by Google. In order to do so it offers you to log in with Google and grant the app access. Now, would you want to do so by putting your Google email and password directly into the app? Of course not. That could give it complete control over your Google account, other apps and sites using your Google identity, possibly services that allow you to pay through your Google wallet... It would be insane to simply hand some phone app your Google login.
So instead with OAuth2 or OpenID Connect you can use the authorization code flow or implicit flow to have the user redirected to the identity provider (Google in our example) where they will complete their login process, and then the identity provider redirects back to the app or a site with an authorization code that can be exchanged for tokens or, for the implicit flow, the tokens themselves.
Now, when it's your own app and your own identity provider (like Keycloak) which are under your control it doesn't really matter. You can use a direct grant to simply have the user input their username and password into the app because you know it's not trying to steal user credentials to maliciously use your service. They're both under your control. In that case OAuth or OIDC are a bit overkill, but you could have separate clients for direct grants (your own app) and authorization code flows (third-party apps using your service). When you want to use Keycloak identity brokering, however, an external identity provider like Google or Facebook is not going to offer a direct grant and invite apps to steal their user's credentials. So you won't be able to interact with them this way.
Depending on what you're trying to achieve you may find some use in the token exchange process. If however the idea is that you want your user to log in with their external identity provider credentials, in your app, without a redirect... Don't.
This is a real use case, unfortunately Keycloak doesn't have a direct way of solving this issue. AWS's "IAM Roles for Service Account" feature works based on token exchange with direct access grant using external IDP. I found this discussion on how to workaround this lack of support in Keycloak but not sure if it solves all the usecases - https://lists.jboss.org/pipermail/keycloak-user/2017-January/009272.html
Do you stick with Direct Access Grant as a method of user authentication in your mobile app? In my opinion, you need to use Authorization Code Flow when the IDP is a third party service as it won't provide an API to authenticate users, and even with your own (first party) IDP, it'd be better to use Authorization Code Flow as stated in OAuth 2.0 Security Best Current Practice section 2.4.
To implement Authorization Code Flow in mobile apps, you will need to use in-app browser tab to show login screen provided by the IDP. Please refer to RFC 8252: OAuth 2.0 for Mobile and Native Apps for details.
I am developing a REST API using Java Spring Boot framework. Purpose of this API is to connect mobile and web applications so they can work together.
My question is, what are the best practices to develop login functions or the login process. Shall I generate a token or what should I do?
You could follow the best practices as described in OWASP, here.
Most APIs nowadays use token based security. Here are a few guidelines:
You need one service (which is itself public) that authenticates the user.
In order to authenticate the user, it might use a username and a password, and/or other means.
As the result of authenticating the user, this service returns an authorization token.
Your backend should keep track of issued tokens.
Each token will have an expiration time.
Every time the client uses an API, it should send along the token. Usually, the token is sent as an HTTP header.
Every service in the API should validate the token before anything else. If the token is invalid, it should return an appropiate HTTP code.
All communications should be sent over SSL.
OAuth and OAuth2 are two very well known protocols for this very goal. OAuth is a little more complicated than OAuth2.
This is a very high level description, not technically deep, but it should get you started.
I'm working on a Java app that uses JavaMail. Currently, I'm trying to connect to a mail provider that uses OAuth2. The provider returns an access token and a refresh token. After sometime, my app doesn't work because the access token has expired. I now need to use my refresh token to get a new access token. However, I'm not sure how to do that in JavaMail.
Is there a way to use the refresh token to get a new access token in JavaMail? If so, how?
Thank you
You don't use JavaMail to do this, since OAuth can be used with other protocols and services. Depending on the OAuth provider, you should be able to issue an HTTP request of the proper form to get a new access token based on the refresh token.
There's some pointers on the JavaMail wiki that might help.
I'm writing a standalone application with accesses the Adwords API. The oauth2 authentication and authorization works fine.
My problem is that I want to save the refreshtoken in a textfile and use it directly the next time I run the app to restore my credentials. The refreshtoken should be valid for 14 days, so restoring the access credentials would very good.
I haven't found an example which works. Can someone help?
The refresh token is not much different from the authorization tokens.
OAuth2.0 has several flows that can be used to get access to the servers. The common (and savest) flow is the so called Authorization Code Flow (detailed info here).
There your application asks the authorization server for an authorization code the first time the user wants to use your application. The user will get that authorization code over the website when he logs in and grants your application access to the service. Your application sends this code to the authorization server in order to get the first access token(and with it the refresh token). It is the same server you need to send the refresh token to.
Now, I don't know exactly what the server's uri is in your case, but this would be an example of a POST request you can send the server:
POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com
Content-Type: application/x-www-form-urlencoded
client_id=YOUR_CLIENT_ID_HERE&
client_secret=YOUR_CLIENT_SECRET_HERE&
refresh_token=THE_REFRESH_TOKEN_HERE&
grant_type=refresh_token
If the request is valid, the server will respond with a new Access Token. Here you can find more informations about the specific requests you can make.
Keep in mind that every token (access- and refresh tokens) have to be stored savely. The best way to do this is to save it encrypted and when sending the tokens use only POST requests and https. But this wasn't your question.
I hope I could help you with this.