I have a 3-legged auth flow working on a web app of mine. It goes as follows:
Use clicks Connect with Google
They accept on the OAuth dialog that Google Provides
The page gets redirect to my backend's /oauth/google endpoint with a code parameter which I send to Google to get a refresh_token so I can access data (like calendar info) on their behalf
I redirect back to the web app passing my own JWT token in the URL.
Whenever the web app makes a request like api.mybackend.com/me they use the JWT token I provided
I'm trying to accomplish something similar in a mobile app. What's the acceptable way to do this? Is it pretty much the same logic?
If it helps, my backend is Ruby on Rails and I'm writing the mobile app in Swift.
Thanks!
If you're using NSURLSession to make HTTP requests, then see this for information about handling redirects.
Google also has some pre-built Google Sign-In packages for iOS and Android that you can include in your app, similar to the one in your web client. I've never used them though, so I don't how exactly they'd integrate with you app.
Alternatively you can set up an authentication endpoint in your backend that handles the whole thing, with the app only ever making one request to your server and your server handling communication with Google. So, for example, you could have the user submit a request to /oauth/mobile. The server then submits an authentication request to Google and gets an access token and a refresh token. Then you can return your own app's token from the server. Google has some documentation on Google Sign-In for server-side apps that may be relevant.
Related
I have really hard time trying to understand mostly how should I implement my authorization flow. I think I have the authentication flow mostly correctly implemented using the technologies I've listed in the title. Here's what I want to achieve:
Basically I have a mobile app built using React-Native and I have made a restful API for this mobile app to use. I am currently at the point that I have implemented authentication using ADFS 4.0. My mobile app directly uses the ADFS endpoints to authenticate the user and I am able to receive the id_token and access token correctly from there. But here comes the part that I have no clue what to do next. Before I used openID, I had my own authentication and just an OAuth2 flow in my Spring REST Api and everytime I made a request from the mobile app to the API, I provided the access token in the headers, and used it to verify from the authorization server that the user is indeed authenticated and also received some crucial information about the user to use in my API. But now since I use OpenID-Connect and ADFS 4.0 for the authentication, I have the cruicial information I need in my API in the id_token. The question is, what exactly should i send to my API now from the mobile app, the id_token, access token or both? Given the access token to the userinfo endpoint at the ADFS returns the subject of the owner of the token. Like is there any way I could receive the users info using the subject or what exactly should I do. I've tried to research this subject a lot, but I am still very confused..
Send the access token to the API in the Bearer header. In the API, validate the token and, if required, do user info lookup. A Spring example of mine here if it helps.
Happy to answer any follow on questions ..
I have the following set up:
A web app (Jetty/Java)
A native client (iOS) (calling my webapp)
The Microsoft Graph API (called from my webapp)
The idea is that the user should sign in with OpenID/Oauth2 using his/her Office 365 credentials. The webapp will then call the Microsoft Graph API on behalf of the user (offline as well).
To achieve this I'm pretty sure I need to use the grant type: "Authorization code grant".
I can find a lot of example of the Oauth2 flow for browser based apps, and for when the native app calls the Graph API directly... but I want my backend to call the Graph API (and hold the access & refresh tokens).
So the question is how to do this properly? Here is my idea at this point.
From the native app: open a browser, call my web server which will trigger a redirect to the Azure /authorize endpoint (example: https://login.microsoftonline.com/[tenant]/oauth2/v2.0/authorize?client_id=[clientid]&response_type=code&scope=offline_access%20user.read%20calendars.readwrite&response_mode=query&state=12345&redirect_uri=my-scheme://oath2-code-reply
This will trigger authentication/authorization and then send the access code back to the app (using a custom scheme redirect: my-scheme://oath2-code-reply).
The app can then call my web app with this access code, where we can exchange the code for refresh & access code, and also create our own session for the user.
Is this the correct way?
Or should the entire flow occur in the browser and as the final step I open the app again with something like myapp-scheme://?sessionid=[our-own-session]?
For your scenario, you should use the on-behalf-of-flow.
A server-side sample that you can use as reference is https://github.com/Azure-Samples/active-directory-dotnet-webapi-onbehalfof - a note is that this sample is a .NET sample using a JavaScript SPA as a client - but hopefully it can guide you. You can use this sample for an overview on how to request tokens for your web api.
A note is that your item '1.' suggests that you are using the 'v2' endpoint. The 'v2' endpoint has some limitations, including for the scenario you are trying to accomplish (request access token to a Web API) - please see this document with information on these limitations, therefore my recommendation is to use the v1 endpoint at this moment for your scenarios -- which mean that you can only authenticate corporate accounts (and not MSA). The documents and samples I've indicated above uses the v1 endpoint.
It's funny but I can't find description of using HTTP requests to receive Google+ authentication code for offline access without iOS Google+ library.
Though example of it's integration is pretty straightforward, I don't want to add additional 20mb of weight to my iOS app.
I tried the approach described here
https://developers.google.com/accounts/docs/OAuth2WebServer#offline
but in case of server clientId I receive message abount incorrect redirect uri.
Could someone give me advice about it?
There are two approaches you could take that may/may not work for you.
Installed app flow with internally stored client secret
Web flow within a web view.
Installed app flow
You will must likely need to use the offline OAuth v2 / installed app flow which has redirect URI that has something like urn:ietf:wg:oauth:2.0:oob enabling you to redirect back to the browser, from there you can get a code to exchange for tokens.
In your case, I'm guessing you didn't create the right client type (installed application) which is preventing the *:oob redirect.
It's less secure to handle sign in in this way - if the user can extract the client secret from your app, they can do bad things like authorize a malicious 3P app with access to your application data.
Web signin flow
An alternative would be to use the web signin flow from within a WebView, something that Apple may reject your app for and which is also insecure.
What you would do is host the sign-in solution on your web server, use the JavaScript web signin flow to initiate sign in, request offline access, then exchange the resulting code for an access token and refresh token.
You would then store the refresh token / access token on the device and exchange it for an access token when you need access to the user data or exchange the refresh token server-side and pass the bearer token back to the iOS app when it needs access. This again is bad because it can expose other apps to user authorization credentials and could potentially allow a malicious 3P to access user data.
I can't recommend either approach. Is there a reason other than the app size impact that you can't use the library? I'll see if there is a good way to avoid the file size hit from the framework.
I've made an app who use OAuth from Google to access to Google Sites API. It works perfectly, but I want less user action, especially the first time when you must accept google's permissions, get authorization token, to get access and refresh token.
I want to know if it's possible to avoid all this steps (for users, and do this behind the application), in the code with HTTP requests for example or google libs, and just have to inform a google account (mail/password) to get an access/refresh token.
Have you any tips or knowledge about this ?
Thanks by advance
As i was using google analytics api i made some research and the minimum process is:
user click authenticate link on your web page, then is redirected to external google webpage when is prompted securely for login and password. and nothing else.
This oauth refresh token you can automate then - read about this in google docs - there is some info about this. i made all by changing a little simple hello world analytics app from google code.
As i remember You had to know what class in php is, and changing oauth wrapper in simple apps. It can store and process refresh tokens automatically - user needs to enter login and password as i said but it can be stored in cookies, so made once.
I'm developing an iOS app that uses the Magento REST API, I'm following the documentation provided by Magento for the OAuth authentication (http://www.magentocommerce.com/api/rest/authentication/oauth_authentication.html)
I use the initiate endpoint to get the request token but then when I want to authorize this token I need to use the "authorize" endpoint and there I get redirected to a URL where I have to provide customer credentials to authorize the request token. This is not the behaviour that I was expecting since the user would be already logged in using the app's login (not implemented yet). Is there a way of making this "authorization" step transparent for the user? Like calling some service passing it the user's credentials provided in the login screen of my app?
If there is no way I'll use the Magento's SOAP API
I did that too really really painful Magento use OAuth1.x, basically you've got three options:
Do it yourself
Use some oAuth consumer lib, you can find them on github
Use MKNetworkKit with this add-on
I used the 3rd because oaf MKNetworkKit, and anyway there was still a lot of work to do, if you want to hide some passages injecting js.