I have a webservice which acts as backend for smartphone apps.
I want to be able to authenticate users as painless as possible, but even though I thought I understood the OAuth I must admit there are some missing pieces here and there.
Authentication:
Let's say the user has an Android phone. He is probably already Authenticated to Google and it would be really nice if I could just extend this authentication to my webservice. Android has OAuth support so the users opens his app, grants permissions to use his google account and the app authenticates him to the web service.
Web service
Since the service should accept users from all kinds of devices it should not be Google specific. It should be possible to register an account and login from any device. I'm unsure if it is possible to register a new account with OAuth alone or if you need some other kind of authentication first - OpenID for instance.
How would the flow be for the generic webservice? A generic API for registering a user and granting him access to an API?
Furthermore - I do not want to control the devices connecting to this service. I can see OAuth requires a consumer_key and a consumer_secret. If I run everything through SSL - is the consumer secret still secret or can I just use some dummy values? Thus avoiding creating a device-registration system where people can acquire a consumer_secret?
For your case, if you want to use Google/Facebook etc as authentication providers, you will need to use the 'Authorization Code' flow of Oauth2. In this case, you register with Google/FB as a developer and get a client id and secret for using their API.
Then you obtain the Login with Google/Facebook button and code, which you will use to fire a "webview" or an embedded browser where the user will be taken to google/facebook and asked to provide his login credentials.
Upon success, an authorization code will be sent to a redirect url that you would have provided while registering as a developer at Google/Facebook. You will need to catch this authorization code and then again call the relevant API to obtain the access token, which you can then use to fetch the user's details to register him in case of first time or authenticate him if he's already registered through this method earlier.
Related
I have a Xamarin forms mobile application that is accessing my app service up in azure. I want to secure the APIs so that only my client application can access them. The mobile app does it's own user/password authentication/authorization, so I don't need AD or a 3rd party for that. I just want to secure my APIs. All examples I can find seems to assume there is an AD user authenticated and I can pass a token from that. Is there a simple way to use the Azure "expose api" functionality without using an AD user? The mobile app is using REST api calls, so I'm also struggling with how to even pass in a proper authentication token if I can put one together. Thanks in advance.
One way to secure is adding an API Management in front of your API's and require subscription, then only calls with a specific ocp-apim-subscription-key will be accepted. I don't recomment storing the ocp-apim-subscription-key value in your app as anytime you need to change it, a new version of the app will be required. I recommend returning it after a succesful login by your users, this way, you're free to rotate the ocp-apim-subscription-key key when needed.
Since you are trying to validate the client application only and not the end user, you should either look into OAuth 2.0 - which has a more complex implementation since it encompasses both application and end user authentications - or you could set up JWT authentication which is simpler and which purpose is to authenticate either client applications or end users, not both at the same time like OAuth.
After your implement the authentication on your API(s), you send over the generated token(s) over a Authentication header on your Requests.
I have to develop a SSO system and I have to do it using IdentityServer4. I have gone through the documentation and examples but I have some doubts. To be honest I don't quite get it, but I am really new in Oauth2 and OpenId Connect.
We will have a bunch of clients (web apps), each of one of those will have their own Web APi. And we have to have a centraliced Login App for all of those. I think the example with the javascript client is the closes to the thing we want to achieve. Also, a user might have permission to access one client (app), but not another, so the IdentityServer must provide information about wich clients (apps), that particularly user can access.
So, These are the things I don Understand:
1.- In the documentation I can read there are two tokens, an Identity Token and Access token. But in the examples all I see are the access tokens. It seems to me that the access token is the one with all de info needed. am I wrong?
2.- Also, I have read about de Grant Types and I'am not quite sure wich one we must use. At first I thought to use the ResourceOwner password, because it requires the client, the secret, a user and a password, wich I assumed it could be the end user. I found this example http://sunilrav.com/post/How-to-Customize-Authentication-in-Identity-Server-4 were one could customise the class that validate the user and password. I thought that this could be the way to go but the documentation statesa about this grant type "...This is so called “non-interactive” authentication and is generally not recommended.". The javascript client example uses the implicit Grat type, wich the documentation states is for browser-based applications (our client apps will all be browser based using react).
3.- can my Login app be a Javascript (react) app? The example Quickstart is made in MVC.NET. This login app connects directly to de IS4 server without asking for a access token? (In the example the app is embebed in the IS4).
4.- Can I protect with IS4 a WEB API which is developed in .net framework (4.6.2) and not in .Net Core? I havent Found Any examples.
the documentatios I followed is the offcial. The examples (quickstart) are also there. (I can't post more than two links).
thank you very much for reading and for your help.
Identity Token and Access token
Identity token is the one that contains the identity of the user, that will tell the client app that what user it is. After successful login, user will be redirected to the client app with these tokens. Response will also have claims, such as permission scopes, name , email you can add custom claims as well.
Access token is used to access your protected web api resource. You have to send the access token with each request to access the api.
Grant Types
Grant types is basically how you want your client app to interact with the auth server. https://identityserver4.readthedocs.io/en/release/topics/grant_types.html
can my Login app be a Javascript (react) app? Your client app can be a javascript app but your auth server that is the identity server which will have the login/signup pages(and other login jazz) and account controllers should be you MVC app. As, everything is already done using MVC and Entity framework, why you want to re do everything.
Can I protect with IS4 a WEB API I am not sure about this one, but I dont see why you would not be able to do it.
This is a good answer for basic IdSrv flow!
UPDATE In my understanding, the answer to which Grant Type to use it depends on your client application requirement. If you want to use a Javascript client you can use Implicit Flow, but you won't be able to use refresh tokens and your access token is not 100% secured with the browser as client can access it.
If you want to open your web api to public then you can use client credentials flow. If you want to be more secure you should use Hybrid flow or HybridClient credential flow. ( again depends on the requirements ). with this you will be able to use refresh tokens and in this way your access token would be more secure.
I'm working on Xamarin.Forms application where user should Authorize using Azure AD B2C. I've managed it just fine using this library.
Now I'd like to know if it is possible to authorize without redirecting to webview. When user enters email and password on app send a get request directly to an url and receive access token, refresh token and etc. Just like in OAuth 2.0.
I've researched and found out that skipping the webview authentication part is doable but extremely not recommended for security reasons but anyway, would be glad to hear any solutions.
Webview runs on SSL (https) and hence transmission of user credentials for authentication is secured.
It’s worth noting that you don’t have to use a web view for authentication; you may create your own user interface for this flow and pass the information back to MSAL.
- this is mentioned on the same blog-post which you referred to.
All you have to do is to design your own interface and pass back the login info. It seems like a little work to do.
I'm in the process of building a Google Chrome extension, and have some questions about how to implement security into the application.
I need to access a couple of Google API's so am going to be using OAuth 2.0 for that. So basically from the extension I know which user is logged into the browser.
My extension then needs to get and post data to my (nodejs) API service. I want to ensure that the user requesting data is the same user that is logged into the browser. Is there any way of using the previous Google authentication process to also authenticate communications between the extension and my API? I dont really want the user to have to log in again, to access my API.
I'm sure I'm missing something simple, and I've not been able to find anything that fits this scenario
Follow the OpenID Connect auth flow and you will get an access_token and an id_token. The acess_token you will use to use to make authenticated requests to Google APIs as usual. The id_token will be used as authentication with requests to your server.
When the requests hit your server you will need to validate the token and you can then use the contents of the id_token to identify the user.
User wouldn't have to login on auth process provided if user is already logged in and you are using a web application flow (not chrome.identity APIs) but user would see the consent screen atleast the first time. However you can skip the account selector screen if you already know the email address by providing &login_hint= parameter.
I'm trying to understand conceptually and practically how to perform an oauth2 with openID-connect flow in my web-api application, utilising Azure AD.
Importantly, when a request is made to the API I want to know who made the request.
My current understanding is :-
My client would detect that the user isn't logged in and redirect to a sign-in.
The user would provide their credentials, and be redirected back to the client, along with an oauth2 token.
This token would be supplied to web-api endpoints for any requests.
This is where it gets murky for me.
How exactly do I use this token to authorize access to a particular resource, determine who is accessing the resource, and what is the mechanism that does so?
I'm sort of assuming that I would need to reuse the token to make a call to the Azure AD user endpoint - if the token was indeed valid, the AD endpoint would return the users details - thereby providing some means of determining that the token is valid and providing details on the users identity. Authorizing access to a resource could be done through membership of groups in Azure AD.
BUT ...
I can only assume this a solved problem, and have noticed use of OWIN middleware as per this example
https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet
But I'm still rather unsure as to what is exactly going on.
The service makes mention of scopes and claims, but I don't understand where these are derived from (I assume from a token supplied by the client, but not sure). The service must be receiving identity information in the call.
Which brings me to two points, for this to be secure -
The token provided in call to the service would need to be secured in transmission (hence the use of HTTPS) - to prevent MITM.
The token would need to be signed some how - I guess by using client secret or something - to prevent information in the token being spoofed.
Can someone help me clear up this muddled mess?
In particular -
How is the identity of the API caller determined - is identity determined from a call in the client or the server?
How to limit access to some endpoints of the API based on a user role?
What do I do to practically achieve this by building on existing middleware and libraries available to me?
Disclaimer: This will not be a comprehensive answer. It is off the top of my head.
OpenID Connect provides an identity layer on top of OAuth. In your case, Active Directory provides the authentication and sends back an access_token. The access token represents a user that AD has authenticated. If your doing OpenID Connect, then AD will also send an id_token, which may contain additional identity information (such as birthday, avatar, and whatever else AD exposes.)
Neither OpenID Connect nor Active Directory have anything to do with the the roles that your app assigns to a user; roles are entirely the bailiwick of your app. You assign user roles just like you normally would; you assign them to the nameid though instead of to an email address or username. Your app no longer has to authenticate the user but it does need to assign roles to the nameid.
How is the identity of the API caller determined - is identity determined from a call in the client or the server?
The identity is embedded in the access_token that AD includes in its response. This token will have a nameid in it that your app can associate with a user and role. The nameid is like an email address, username, or other uniqueID that your app uses to recognize the user.
How to limit access to some endpoints of the API based on a user role?
You choose. When your app receives a request with a particular access_token, that token will be associated with a particular user via its nameid, and you can assign whatever roles and rights to that user. Basically, associate roles with a nameid.
What do I do to practically achieve this by building on existing middleware and libraries available to me?
There is an unfinished demo here, though it doesn't use Active Directory as the provider, instead, it uses an internal provider. For the demo, the username is shaun and password is Testing123!. The source code is here.
Here is the link to the source of another demo, though again, it doesn't use Active Directory as the provider, instead, it uses Twitter.
The nice thing about OAuth and OpenID Connect is that we can use whatever identity provider we want, so you can adapt the demos to use Active Directory.
Apart from question #1 (the identity is verified on the service side) all your question are very open ended and would require a super long answer.
I would recommend reading https://azure.microsoft.com/en-us/documentation/articles/active-directory-authentication-scenarios/ - it is a good introduction to the flows underlying many of the modern authentication cenarios, including the web API one you are focusing on.
Once you have read that, you will find a complete set of samples in https://azure.microsoft.com/en-us/documentation/articles/active-directory-code-samples/ - in particular, I suggest studying the web API and thru authorization one to find guidance on the 3 questions you listed. HTH!