How does Azure Active Directory authentication for Azure API Apps work? - authentication

I'm trying to call an Azure API App configured with Azure AD authentication. Assume for the purposes of this question I cannot use the Azure SDK and need to write code to get a token and insert it into the API request.*
I have established that there are two modes - 'client flow' and 'server flow', where client flow entails following at least one redirect to an issuer to get a token, and server flow where the server does this for you. Since I'm talking about doing this in code, following redirects would be possible but fiddly, so I'd prefer to use a mode where the URI or URIs to visit are known ahead of time and return content, rather than redirecting. The following diagram illustrates how the gateway routes all requests.
I think the mode I need is client flow, which would go something like:
Get an access token from the identity provider (which is what? how do I find out where this resides? what is the format of the request I have to send to the IdP?)
Pass the access token to the gateway (in what format?)
Receive another token in the gateway response
Supply this token in a header when making an API request (which header?)
How am I supposed to do this? The Azure documentation doesn't give enough detail about how it works, and expects all users to just use the SDK, which hides what is actually happening.
The actual reason is that ultimately this will need to be called from BizTalk, which uses the WCF WebHttpBinding to call restful services. I'm writing a custom behaviour to insert a token header into the request, but I need to know how this token should be acquired. It's possible to run arbitrary code in BizTalk but trying to do this makes the solution complicated, and config-only or mostly-config with minimal, loosely-coupled code is the simpler solution

Just want to understand your scenario better, Because you are going to use it from BizTalk Receive Pipeline, The scenario can be simplified by enabling a customer authentication token right ? Basic username and password for your API you have hosted on the cloud. Does BizTalk want to authenticate it self with tokens for each AD User ?
To answer some of your questions
Get an access token from the identity provider (which is what? how do I find out where this resides? what is the format of the request I have to send to the IdP?)
After you have configured your AD configuration, Once you have completed the authentication, I am assuming your are using ASP.Net here, You can find everything you need about the claims on your Thread.CurrentPrincipal, You can convert it to ClaimsPrincipal like so var claimsPrincipal = Thread.CurrentPrincipal as ClaimsPrincipal; and then you will find a lot of good information on this object. Name of the user logged in, list of claims the principal has etc. I have not explored every avenue here, but this should be a good starting point.
Your API App is running on this process which means you have access to these claims in your API App code as well.
I would build a custom pipeline in BizTalk that uses Azure SDK to authenciate and build this scenario, it is a bit complicated but it will give you more control over what goes through the pipeline as well when authentication fails with permission issues and so on.

Related

Questions about Native applications and openId Authorization code flow

I have a few concerns with an OpenId Connect strategy that I would like to use and have been unable to find specifics on what the security concerns may be and any glaring issues with it I am overlooking.
Currently, I have an OpenId Connect implementation using Openiddict with Authorization Code flow. For the client, I have a React-Native app using react-native-app-auth.
I see from other questions on SO and from issues posted on the Openiddict repo that the recommended approach to third-party providers (e.g. Google) is: Client -> Auth server -> Google Auth -> Auth server -> Client/Auth server code and token exchange
However, it seems that a better approach from a UX standpoint (when using a SPA or native app) would be to implement something similar to GoogleSignIn on the client and either handle the identity on the server using an IdToken or authorization code from Google. This introduces an issue as the flow previously recommended could not be used as the entire initial challenge and redirect from Auth server to Google Auth has been skipped.
I have seen that this issue is mitigated by not using the authorization code grant and instead implementing a custom assertion grant. This seems to be an alright approach but would require exposing a custom grant and handling the flow differently on the client and server for local and third-party logins.
My proposed solution continues to use the authorization code flow and instead of adding a custom grant type the client could just pass a third-party identifier "Google" and the token or authorization code in the additional parameters of the OIDC authorize request. The authorize endpoint could then detect the provider and token, perform token validation, create a user or principal from it, and create an authorization code to send back to the client for the code/token exchange. This flow would look like the following:
1. Get the id token from the provider Client -> GoogleSignIn -> Client
2. Pass token to auth server and initiate code / token exchange Client -> Auth Server -> Auth server Verify Google IdToken (JWKS, issuer, audience, provider specific validation, etc...) or exchange auth code -> Auth server -> Client/Auth server code and token exchange
One downside to this approach would be the additional hops to verify the token on the server side. If the token was returned from GoogleSignIn, they themselves said that it could be trusted. https://developers.google.com/identity/protocols/oauth2/openid-connect#obtainuserinfo
I see that it is generally recommended to place the auth server between the client and the third-party but in this process the server is still between the client and auth server but only after the initial exchange from the client and third-party.
Questions,
In general am I missing something with this flow?
In this case would it be necessary to verify the token on the server side?
Is there some better way to approach this that I have completely overlooked?
Am I making this too complicated and UX should not be this much of a concern?
Instead of adding the provider and token to the additional parameters would it make more sense to pass it in the body of a post request? I don't see the issue with passing it via query string but that's also part of the reasoning for the authorization code grant from my understanding.
Apologies in advance for anything I have missed or omitted for brevity that should have been included.
Thanks.
ARCHITECTURE
I'm not sure I understand the UX problem - your existing architecture feels really good. If you want to login directly to Google, just send an acr_values=google query parameter in the authorization redirect, to bypass any authentication selection screens. The exact value will depend on how Openiddict represents the Google authentication option, and some providers use a non-standard parameter such as idp. Have a closer look at the OIDC request parameters.
A key OAuth goal is that the Authorization Server (AS) - Openiddict in your case - shields your apps from all of the provider differences and deals with their nuances and vendor specific behaviour. Your apps then also only receive one type of token, and only ever use simple code. As an example, the Curity AS supports all of these options, none of which requires any code in applications.
APPAUTH AND UX
If a user is already signed in then it can, as you say, look unnatural to spin up the system browser and them it is dismissed immediately.
A common option is to show the consent screen or an interstitial page to keep the user informed - and the user clicks one extra button. This can also be useful for getting password autofill to work. My code example and blog post shows how this might look, though of course you can improve on my basic UX.
OFFLINE ACCESS
I find this term misleading, since refresh tokens are most commonly used when the user is there. Are you just asking how to deal with tokens in a mobile client? Aim for behaviour like this:
Standard messages for API calls with access tokens in an authorization bearer header
Standard refresh token grant messages to refresh access tokens - eg as in this code
Note also that mobile apps can save tokens to encrypted secure mobile storage that is private to the app. This can improve usability, eg by avoiding logins every time the app is restarted. You should think through scenarios such as stolen devices and token lifetimes though.

Integration of frontend and resource server using okta authentication and client credentials API authentication

We have an application that has frontend UI(Which is a web application) which communicates with a resource server. Our frontend will be using some APIs from a resource server to get data.
I am planning to add frontend to Okta and provide access to okta registered users.
In the resource server, we have some APIs that we want to expose to our customers to integrate in their system(Programmatically). To use our APIs, we have to provide client credentials(client ID/secret) to them. Using clientId/Secret, they will get access_token and will use that in a subsequent request. We can display this clientId/Secret via frontend UI once the user logs in to it via Okta.
How should I authenticate requests to the resource server from the frontend? And how do I authenticate requests to resource server via customer using clientId/Secret? Should I use one or two different tokens for this purpose?
Does Okta provides per-user client Id/secret that user(customer) can use to get access_token and send it to access resource server and resource server validate token against Okta.
I just did something very similar. You can read about my experience here: How to pass/verify Open ID token between .net core web app and web api?
I don't know what application framework you are using (.net, node, etc), but if you're using .NET the steps are to (a) install the middleware in your web app, (b) install the middleware in your api app, and (c) make sure calls from your web app to the api app pass the id_token.
If you, in addition to that, need to secure it for external users - it should work the same way. The only difference is they will manually call the /authorize endpoint to get their token - but the middleware should take care of the token verification for you in both cases.
Note I did experience one odd thing which is that I needed to pass the id_token and not the access_token. It is also worth mentioning that the claims were interpreted differently in the app and the api (in that the name of the claims for say, userid, were different between them - the data was still the same).
You will have to use 2 different access tokens. There are 2 different flows going on here:
Web UI to API
Business partner system to API
Technically this means:
Authorization Code Flow (PKCE)
Client Credentials Flow
And in terms of tokens it means:
In the first case there is an end user represented in access tokens (the 'sub' claim)
In the second case there is only a Client Id claim in access tokens
I can advise on token validation techniques if needed - let me know.
To me though this feels like an architectural question - in particular around applying authorization after identifying the caller and versioning / upgrades.
Based on my experience I tend to prefer the following architecture these days, based on 2 levels of APIs: eg with these ones exposed to the internet:
User Experience API serves the UI
Partner API deals with B2B
And both entry point APIs call the same core services which are internal. Might be worth discussing with your stakeholders ..

Authentication flow for temporary credentials in the browser

I'm trying to wrap my head around a specific proprietary authentication flow used by one of our customers, and how to implement it in IdentityServer4.
We're developing an SPA with some microservices as backend and do all our authentication/authorization with IdentityServer4. The standard workflow for the SPA is (as expected, I guess) the implicit flow using oidc-client-js (for now).
Now the problem: one of our customers has something like a homebrew SSO solution dating way back. Users basically authenticate at a central portal and get a link to the application with a token attached. This token is valid for a few minutes and contains the temporary user credentials, I need to somehow authenticate at our IdentityServer.
My first attempt was the client credentials flow. Doesn't work, as the client cannot refresh its access token later, once the initial credential token ran out (the client does not and cannot have access to permanent credentials.) My current approach would be to kind of "hijack" the implicit flow, by authenticating with the given temporary credentials and from there on out use the normal refresh cycle without further need for any credentials.
Is this a valid approach or am I completely on the wrong track? If it's valid: how do I get IdentityServer4 to do my bidding? I cannot use IResourceOwnerPasswordValidator, because that would require the client credentials flow (I think?). Is an IExtensionGrantValidator the way to go? (If so: any ideas, how to convince oidc-client-js to use a custom grant?)
Thanks for your help.
Regards,
Markus

Browser and Webserver api authentication tokens

I am currently working on a solution that includes a multi tenant webApi which will be accessed by multiple clients, some of which i will be creating, some of which others will be creating.
Access to the api will be available via an ApiKey & Secret (enough for some resources) as well as username & password (for owner resources).
At the moment, the clients i have created (.Net MVC Web apps) have their own membership systems so what happens is the user of the client logs into the client system and the client system passes the login information to the Api to retrieve an authentication token.
The client membership system is really an unneeded abstraction. What i really want to do is have the user log directly into the api and the api pass back an authentication token that can be used from the browser as well as the .Net MVC client app.
My question is, what it the best way to achieve this. In my mind i seem to be struggling with 2 solutions.
1) Have a browser based login (ajax/AngularJS for instance) solution that calls the api to retrieve a token which then passes that token onto the MVC client where it will be stored (session variable maybe). Any future calls to the api that come from the .Net MVC client can pass the token on. This seems wrong to me though. I'm not even sure this is possible.
2) Utilise one of the OAuth flows so that the browser based login can call the API and retrieve a token, and the OAuth flow redirects to the MVC client which then stores the token for that user (again, in a session variable).
The Api was generated using the VS2013 WebApi template using Owin local accounts and is generating tokens via the ValidateClientCredentials and ValidateResourceOwnerCredentials flows, but i think i need to use one of the other OAuth flows for this scenario.
I understand that another solution would be to bypass the .Net MVC client code and create a completely browser based solution using knockout or AngluarJS but it's quite a complex system and i don't really have time to do this at the moment so i'm looking for a solution that would allow me to retrieve a token from the api that can be used from my .Net MVC client and ajax calls from the browser.
Any ideas, advice would be much appreciated.
thanks in advance. Justin
If you'd rely on Azure AD as your credentials store and authentication system, you'd be able to leverage a ready to use JS library that handles authentication, AJAX calls and session management concerns automatically: see http://www.cloudidentity.com/blog/2014/10/28/adal-javascript-and-angularjs-deep-dive/.
If you can't rely on Azure AD, the code of the library and samples mentioned above can still have value as a reference to build your own system - provided that the authenticaiton system you decide to use offers similar capabilities.
HTH
V.

How to maintain user session in the client?

So I have a REST API. I followed this tutorial in setting up client authentication. I'm done with that. Now the next part is user authentication. What I have in mind is like this:
The client sends the login details to the API.
The API validates the username and password and generates a token that is sent back to the client.
The client stores the token somewhere and use it for authentication for subsequent requests.
The questions, is this a proper way of maintaining sessions in setups like this? Are there better ways in implementing this? I'm very new to this type of thing so please be elaborate with your answers. Please note that the API is pure REST and client could be anything(eg. Angular, iOS, Android app). So it's not typical in the sense that the front-end is not on the same server as the API.
You could do that but you would be going off the beaten track of proven security patterns. This probably isn't wise and will give you lots of extra work and headaches. However, here's one service provider that exposes a REST API and created their own extension of OAuth. It is similar to what you outlined so I list the steps here to serve as an example but not necessarily recommending you follow:
Consumer Application collects the User's credentials directly
Consumer Application concatenates the user name and password with a space and base64 encodes the credentials
Consumer Application puts the encoded credentials in the body of the request. Credentials must be URL Encoded after they are base64 encoded
Consumer Application posts them to a designated URI (example: api.com/v1/user/accesstoken)
This request is signed using OAuth signing requests
The Service Provider will hand the Consumer Application back an Access Token
The Consumer Application will access the User's data using the Access Token