I am developing an application using ASP.NET MVC 5.2.2, Web API 2.2 and Katana/OWIN 3.0. The application uses ASP.NET Identity 2.1 for local accounts and database.
I am using OAuth Authorization Server to generate access and refresh token. I have Android and IOS apps which uses my local oauth authorization server. Android and IOS apps uses SDK to login with Facebook, Google, etc. After that the apps will send the (Facebook/Google/etc) access token to the server. The server will validate access token with Facebook/Google/etc.
If it is valid then,
1) Should I generate new local access token(in Auth header) to apps
for all future request?
2) Should the app send me Facebook/Gmail/etc
access token(in Auth header) every time and the server validate the
access token with Facebook/Gmail/etc each time?
3) If local access
token expire, then the server is using refresh token to generate new
access token. Should the server update the access token as well as
refresh token during this time or updating access token is enough?
after you validate your social provider external access token, you need to exchange this external access token with a local access token issued by your authorization server (Local authority). All the details for this implementation can be found here: http://bitoftech.net/2014/08/11/asp-net-web-api-2-external-logins-social-logins-facebook-google-angularjs-app/
Let me know if this helps.
Here is the exact steps I have followed to change the external access token with access token issues by Local Authority. The front end is an AngularJS application. You can check the demo application here and see how I'm accessing the web api using Facebook access token http://ngauthenticationweb.azurewebsites.net/
1- AngularJS application sends HTTP GET request to anonymous end point (/ExternalLogin) defined in our back-end API by specifying client_id, redirect_uri, response_type.
2- Once the end point receives the GET request, it will check if the user is authenticated, and let we assume he is not authenticated, so it will notify the middleware responsible for the requested external provider to take the responsibility for this call, in our case it is Google.
3- The consent screen for Google will be shown, and the user will provide his Google credentials to authenticate.
4- Google will callback our back-end API and Google will set an external cookie containing the outcome of the authentication from Google (contains all the claims from the external provider for the user).
5- Google middleware will be listing for an event named “Authenticated” where we’ll have the chance to read all external claims set by Google. In our case we’ll be interested in reading the claim named “AccessToken” which represents a Google Access Token, where the issuer for this claim is not LOCAL AUTHORITY, so we can’t use this access token directly to authorize calls to our secure back-end API endpoints.
6- Then we’ll set the external provider external access token as custom claim named “ExternalAccessToken” and Google middleware will redirect back the end point (/ExternalLogin).
7- Now the user is authenticated using the external cookie so we need to check that the client_id and redirect_uri set in the initial request are valid and this client is configured to redirect for the specified URI.
8- Now the code checks if the external user_id along with the provider is already registered as local database account (with no password), in both cases the code will issue 302 redirect to the specified URI in the redirect_uri parameter, this URI will contain the following (“External Access Token”, “Has Local Account”, “Provider”, “External User Name”) as URL hash fragment not a query string.
9- Once the AngularJS application receives the response, it will decide based on it if the user has local database account or not, based on this it will issue a request to one of the end points (/RegisterExternal or /ObtainLocalAccessToken). Both end points accept the external access token which will be used for verification and then using it to obtain local access token issued by LOCAL AUTHORITY. This local access token could be used to access our back-end API secured end points.
Related
I am trying to write an application that:
In a browser, authenticates a user with a Google account.
Calls a backend service.
Backend access user's drive (and some other things) and then returns JSON.
Frontend: copied some example from the web, can authenticate without issues.
Backend: Node.js/Passport.js. Copied the code from an example, can authenticate.
But how do I authenticate a user in the browser and then do an API call so the API may access the Google Drive? What is the expected flow?
A. Web app authenticates the users then passes id_token to the server?
Can't find how to implement this on a server...
or:
B. Server sends app to, say, /auth/google/ on the same server, then app gets a token from server?
Think of OAuth2 as a permission delegation protocol - user (Resource owner) authenticates and gives a consent to passing an access token (or some other tokens) to the OAuth2 client that initiated the process. When the client receives the access token, it can act on behalf of he user and access resources on a resource server (Google Drive).
So if your backend wants to access Google Drive, the cleanest way would be to make your backend an OAuth2 client, that redirects a user to Google auth server and then receives an auth code. The client must ask for scopes that will allow it to access Google Drive. The auth code can be exchanged for an access token. To access Google Drive, the backend needs to send a valid access token in the Authorization HTTP header of the request.
If you need the tokens on your frontend as well, you can use it as an OAuth2 client and pass them to the backend in an HTTP header.
Currently I have this setup:
At login, and in every subsequent request after login, a mobile application that I have built uses Basic Authentication to authenticate the user with a web service that serves the app with information it requests.
On every request the Authorization header is inspected, the password and username are extracted from the header, the password is hashed using a proprietary DLL (so the web service doesn't actually contain the hashing algorithm) and compared to the hashed password associated with the username that is stored in the database.
I have now been asked to include Azure AD SSO in the login options.
After reading much about the topic, this looks seems to me like the setup:
I'm curious about a few things:
Is this setup correct, more or less?
Does the app send the Identity Token to the web service? If so, how does the webservice validate that token?
Is it correct that the webservice can match the Azure Identity to the DB user using one of the claims in the Security Token?
Where do Access Token fit in this picture?
Thanks for the help!
(Side Note: I know that Basic Authentication is not the preferred way to go in the first scenario. This was a temporary decision till we developed the token handling code, it only works using HTTPS and this is an internal application - you wouldn't be able to activate the app unless you have a code we give you)
I have little experience in azure ad but I think we could talk about your case.
First, whatever id token and access token are both jwt token, so to your web service application, you need to use jwt decode library to decrypt the token and get claims it contains. Here we need to know the difference between id token and access token, and I think you'll know that for your web service application, if it's more likely to play the role of an api application, you need to use access token because this token also contains user information. Then you need to add code in your program to decode the token and check if it's a 'valid' token for the request.(Because you've used azure ad to achieve the login part, you don't need to use your custom login part.)
Next, the signing in feature provided by azure ad requires to use account and password in the tenant which azure ad belongs to, the user accounts may look like xx#xx.onmicrosoft.com, it doesn't required to keep sycn with the accounts in your database, so it's difficult and needless for you to compare the user name obtained from the decoded token with those in your database. Because when your web service received the token(id or access token), that means someone has passed the authentication from azure ad. The token contains user information including role, expired time etc. You need to check if the token has expired and if has the correct scope. (Let's see a common situation, microsoft provides many graph apis to call, when accessing these api, we need to provide access token in request head with matching scope, e.g. https://graph.microsoft.com/v1.0/me
requires a delegated api permission of User.Read)
To sum up here, if your web service just required the users in your database to sign in then can be access, id token and access token are both suitable for you because they both contains user name like 'xx#xx.onmicrosoft.com', what you need to do is decode the token and check if the token has expired and whether this user exists in your database(you may set up a mapping between them).
I am trying to figure out how to perform single sign on with OAUTH2 on two different applications. Currently according to my understanding I can use the Authentication Provider in order to authenticate my clients. The procedure is the following:
The client is redirected to the Authentication Provider
Then the client is loggedin and has the code
The client provides the code to my application
The server uses the code in order to retrieve the access token.
Using the access token my server uses the remote API to retrieve information
Now I have a second application in a different backend (PHP) that I want to inform that the user is already loged in via the OAUTH. My naive solution is to provide the access token of the first application to the second application in order to perform the authentication. However, I understand that I am not allowed to share the access tokens between apps.
Every backend service should validate the access token via introspection. The only introspection guarantees that the token is valid, not expired or revoked.
So you have to pass the access token to the Backend service. To secure that you can use HTTPS API.
You are correct regarding not sharing the access token. The Authentication Provider should also allow creating an ID token. You would configure your second application with the authentication provider and get a client id. Both the client id and ID token are required to sign in the second app which will generate it's access token.
What grant type are you using?
Both apps need to redirect the user:
In the first app the user will authenticate and the app will get an access token scoped to that app.
In the second app the user will be automatically signed in without needing to reauthenticate. The app will then get a separate access token, generally with different privileges to that of the first app.
This is standard SSO behaviour and it is best to accept it. Usability is pretty good. Trying to share tokens is not advised unless you have advanced requirements.
I am new to OAuth and OpenId, and after reading multiple pages and information I still do not feel confident at all.
My goal would be to create an iOS Application that communicates with my BE. I need the iOS app to authenticate the user to access their resources.
Reading about OAuth, the solution seems to be straight forward. Just use the Authorization Code Flow with PKCE to make the App have an Access Token. This way I am authorizing my iOS app to access user's data. When the iOS app calls https://example.org/user with the access token, the resource service (my BE server) can get the access token and call the introspection API to know to which user the access token is bound to, and return the correct user data. Since authorization needs authentication to be made in the first place, having the access token would mean that the user is (or at least was) authenticated.
First thing that confuses me: According to the OAuth specs, OAuth is not an authentication protocol, but still the protocol authenticates the user using the user's credentials. Why is OAuth asking the user for credentials, instead of relying on another protocol/flow for user authentication? Such protocol would just acknowledge to OAuth that the authentication was successful.
This first issue made me start reading about Open ID Connect specification and the ID Token. This token would be received by the iOS app. What is the iOS App supposed to do with it? I can already get the user information calling the /user endpoint. How would this ID Token be an advantage?
tldr
Access token (OAuth 2.0) - authorize against OAuth protected
endpoints.
ID Token (OIDC) - authentiation by client application.
Authorization server authentication - It's there to detect
authenticity of end user involved in both protocols (pseudo
authentication from client application perspective)
OAuth is not an authentication protocol, but still the protocol contain a step to authenticate the user using the user's credentials
Correct, OAuth is not an authentication protocol. It is for authorization, which means identifying there are correct access grants to access a protected resource (protected resource ? ex:- An API, A photo stored in a backend).
So why you see end user login dialog ? Well that is the job of authorization server. It authenticate end user to be known by it and then issue the access token to client (client == in simple terms the application which end user uses). So yes there is an authenitcation happening, but this is not applicable to your client application or protected endpoint. One can define this as an pseudo authentication.
OpenID Connect - For authentication of client application
In the original RFC (RFC-6749), OAuth 2.0 was defined as a framework. OpenID Connect was an extension that built on this framework. What it provide ? Well as you found out, it introduce the ID Token. And ID token is issued by authorization server to be consumed by your client application. It contains end user identity information in JWT format. By validating integrity of this token, your client application can authenticate the end user. And access token ? That's there to used against protected endpoint. It doesn't say anything about end user to client.
I am using laravel passport for authorization from mobile app.
But I'm not sure where to place the client credentials i.e client_id/client_secret and redirect_uri.
Will it be placed at mobile app end and they will pass these to an API while authenticating to get tokens or these details be kept at server side in some env variables for security purpose?
And will the every user be having different client_id and secret or it will be same for all users throughout the application.
The client credentials grant type is for when you want your application to contact the server with out a user. For example a weather app will contact the server to get the latest weather data. It does not need to user to login to do this. You want to client credentials because you do not want everyone using your api. It is a way to protect your api and only allow your approved apps to access the api information.
Yes you will pass the client_id/client_secret from your mobile/desktop application to the /oauth/token url on your server so it will return an access token for you to use when getting all the information through the api.
The client_id and client secret do not need a user. It is for the client (Mobile/Desktop application). But it will be the same for every user since they all will be using the same mobile/Desktop application.