Securing Azure App Service API calls without passing user credentials - azure

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.

Related

User Authentication with IdentityServer and Azure API Management

I need some help with Azure API Management service.
At the moment we have a SinglePage App which is using two Backend Services (WebApi .Net Core) hosted on Azure. To Authenticate and Authrize user we are using IdentityServer (also hosted on Azure as a service) + SubscriptionService. Here IdSrv is authenticating the user and it also defines to which APIs the webapp has access. The SubscriptionService has information if the user has rights to given APIs. More or less like that.
So the flow is:
WebApp -> redirect to IdSrv endpoint -> login -> back to UI -> ask backend with user credentials (token)
Now, we want to add Azure API Management to the mix and I am struggling how to do that...
Initially we were thinking that we can hide everything including the IdentityServer behind API Management gateway, but looks like this doesn't make sense or is impossible. I found this as a helpfull reference: Generate Access Token and validate against IdentityServer4 through Azure API Management in which the second answer is quite important remark.
Based on that I think that I need to leave the Client to use IdentityServer to authenticate as this requires UI interaction but then somehow set a global policy in API Management to authorize the user using mentioned Send-Request policy. And then change backend to accept the JWT tokens from this policy? Is my thinking correct? How to implement that?
Or I should just pass the authorization-header from client request through API Management?
All those things are new for me so it could be that I missed something or messed up the terms...
The way you integrate APIM into picture may depend on goals you want to achieve with APIM. You could hide IdSrv behind APIM since there is Client credentials flow that would allow APIM to authenticate/authorize itself to an API, or you could have user authorize APIM once via Auth code grant and then store refresh tokens and use them to talk to an API. But I'm not sure that would be best since it quite a bit changes you system and forces you to solve other problems instead, like how to authenticate user to APIM. In some cases this may be a good approach, it's up to you to decide.
If you're fine with keeping IdSrv facing user, then we have APIM receiving a token with every request. You could then have a global/API policy in APIM that would send token received from user to SUbscriptionService to check user authorization to make a call) can do that with send-request policy), and either let the call pass or deny. This approach is most useful if you want to use different auth mechanism between APIM and backend, because if APIM is doing authorization work, your backend could avoid checking any user access, and instead just authorize APIM to do everything.
Check out this sample on how to authorize requests using external service: https://learn.microsoft.com/en-us/azure/api-management/policies/authorize-request-using-external-authorizer
it is quite late from asking this question but here I described how we have done that. We cover UI clients and Device clients with SSL Certification auth on APIM. In short words:
UI Client is being redirected to ID Server Loging page
APIM is doing Token validation with ID Server
APIM is doing SSL Certification verification in DB and returning back token like data for devices to pass some "device account" information.
More details can be found here:

Can two Azure web applications use the same token for authentication?

I've got a SPA application and an associated API from which it gets its data. (Aurelia and Nodejs)
I have recently worked out the Authentication on the SPA so that it uses MSAL to authenticate users against our company's AAD and is able to retrieve a token that the app can then use to access the MS Graph as well.
However, I also want my API to authenticate against the AAD. What I'd like is for the API to be able to accept the token from the SPA client.
While I am able to send the token from the client to the API (Authorization: 'Bearer'...) I'm not sure what to do with it on the server side to then verify with the identity provider that the token is valid.
For the most part, I don't want the API to have UI concerns (i.e. an authentication/login screen). It should simply reject any requests that do not carry the correct token.
I hope to eventually have both client and server apps being hosted as App Services on Azure, but for the time being they are hosted internally. I think there is a way to ensure the solution works regardless of where the apps are hosted.
Thanks for your help!
I am not sure I understand the relationship between the title and the body of the question: I will answer the body :)
In https://azure.microsoft.com/en-us/resources/samples/active-directory-b2c-javascript-msal-singlepageapp/ you can see an example of web API token validation in Node JS. The service side logic just needs to be adjusted to point to the Azure AD tenant you are using.
The above will work regardless of where the API is hosted, given that the parameters being validated are all about logical identifiers.

Why is MSDN telling me to create a OAuth2.0 client when I just want a barebone test for my API?

I have a REST API, written with express directly. Nowhere in it do I use session, and authentification is for now done using JWT.
However, I dislike having to handle, save and secure user's credentials, that is when I heard about Azure Active Directory.
Adding passport to my app was easy enought, but that's when trouble started.
First, I had to search what strategy I needed, and all of them seems to require the server to maintain sessions/remember who is logged in, all the while using JWT internally. That seems contradictory, JWT is supposed to remove the need of maintaining session.
Finally, I found this MS example which use the Bearer strategy without session.
After setting it up (changing the config file for the right tenant, client ID, changing the routes for a test app more representative of my API), I tried to use them. The protection work well since I am indeed "Unauthorized". But how do I get a valid token to send?
The MSDN guide that use that quickstart don't mention it at all, just redirecting to the AAD library for Android or iOS, implicitely telling me to develop a test app in another language when I just want a crude tool to test if my test server work at all!
That is especially frustrating since I am pretty sure it is "just" a series of HTTP(S) request on the tenant, and the call to the api with the token attached, but I can't find anything to do just that.
/!\: I know asking for something as vague as "How can I do that" isn't a good question, and this question isn't one. What I am asking is why I couldn't find some tools like POSTMan that implement OAuth and allow to quickly test and debug a OAuth protected API. What are the reason that push MSDN to tell me to write a custom tool myself instead of providing a barebone one?
The code sample you mentioned in the post is using the Azure AD V2.0 endpoint. We can use OAuth 2.0 code grant and client credentials flows to acquire the token from this endpoint.
To compose the OAuth 2.0 request directly you can refer the links below:
v2.0 Protocols - OAuth 2.0 Authorization Code Flow
Azure Active Directory v2.0 and the OAuth 2.0 client credentials flow
In addition, the access tokens issued by the v2.0 endpoint can be consumed only by Microsoft Services. Your apps shouldn't need to perform any validation or inspection of access tokens for any of the currently supported scenarios. You can treat access tokens as completely opaque. They are just strings that your app can pass to Microsoft in HTTP requests(refer here).
If you want to protect the custom web API with Azure AD, you can use the Azure AD v1.0 endpoint.
For getting a valid token to send to your API, you'll need to do an auth request to login.microsoftonline.com and get an access token (in the JWT format). Then you can send this token to your api in the http body: "Bearer ey...".
If you want a full sample with a client app that hits that API sample you tried:
Dashboard w/ all the samples for Azure AD Converged Apps
Simple Windows Desktop App
Angular SPA
Node Web API

How to secure an API when the consumer uses claims authentication

Background
I'm building a .NET MVC enterprise web application that must have the ability to authenticate users from different companies. One of the major requirements was to ensure that users don't need to create and remember new credentials to use the application, instead they should continue to use whatever credentials they use to access applications within their company intranet.
Since the application will be hosted on the extranet and needs to handle authenticating against multiple domains (i.e. multiple Active Directories), we are expecting each client to set up a security token service (AD FS) that the application can interface with to implement claims authentication.
The MVC application will check if the user is authenticated, and if not, start the workflow that ends with the MVC application being given a SAML claim being associated with the user.
Problem
At this point, the user is authenticated and given access to the MVC application. However, the application itself is a modern day web application that uses quite a bit of JavaScript to consume a .NET Web API that handles most of the business logic. My main question is how I can secure this API. I want to make sure the only requests being sent to this server are being sent from a valid source, and that the user consuming the service has permissions to do so.
Current Solutions
There are two approaches I can take to consume the API:
Straight from JavaScript (Preferred solution)
Route the request through the MVC server, which will then forward it to the API.
In order to pick an approach, I first need to find a way to secure the API.
HMAC Authentication
The most straight forward solution I've found is HMAC Authentication - http://bitoftech.net/2014/12/15/secure-asp-net-web-api-using-api-key-authentication-hmac-authentication/. However, this approach requires all API requests to come directly from the MVC server, since the secret key will need to sit on the MVC server.
OAuth 2.0
The second approach I can implement is some flavor of OAuth 2.0. The flavors I'm familiar with can be found here http://alexbilbie.com/guide-to-oauth-2-grants/:
Authorization Code
Implicit
Resource owner credentials
Client credentials
Authorization Code Grant
This is not the approach that I want to take. The MVC application has already received claims for the user - they shouldn't have to do it again just because the API needs the claim. (I have a followup question asking if I can simply pass the claim to the API server)
Implicit Grant
I like the way this approach sounds, since I will be able to execute API requests in the client (i.e. JavaScript code), however it suffers from the same problem as the first approach.
Resource Owner Credentials Grant
This approach is out of the question - I don't want either the MVC application or the API to ever hold onto the user's credentials.
Client Credentials Grant
This approach is the only reasonable OAuth approach listed - however I fail to see a major difference between this approach and HMAC authentication detailed above.
Questions
Have I correctly set up the MVC application's authentication structure? Specifically, in this context is it appropriate to have AD FS handle authentication and respond with SAML tokens representing user claims?
I plan to store user data in the server's session. Can I also store the user's claim in the session, and then somehow send that up to the API for authentication?
If I can pass the claim from the MVC server to the API server, and the API server can correctly authenticate the request, is it safe to pass the claim to the client (browser / JS code) so that consuming the API can bypass the MVC server?
Is the HMAC Authentication approach the best way to go?
Yes, using ADFS or any IdP products as an IdP for your application is a good way to implement SSO. Doing this way help you delegate all the federated access management as well as claim rules to ADFS.
Yes, you can store claims in session and somehow send them to the WebAPI. Please note that if you are using WIF, it already stores claims in Thread.CurrentPrincipal as a ClaimsPrincipal object. Another thing is that I assume you only want to somehow send the claims only, not the whole SAML2 token.
I would say it is as safe as the mechanism you use to protect the token on the client side. Check https://auth0.com/blog/ten-things-you-should-know-about-tokens-and-cookies/ and https://security.stackexchange.com/questions/80727/best-place-to-store-authentication-tokens-client-side for more details.
I can't say if it is best for you, but it seems to be a viable way, given that you have control over the WebAPI too. However, it also seems that using JWT token would be easier: https://vosseburchttechblog.azurewebsites.net/index.php/2015/09/19/generating-and-consuming-json-web-tokens-with-net/. Talking about JWT token, you can also ask ADFS to issue it for you: https://blogs.technet.microsoft.com/maheshu/2015/05/26/json-web-token-jwt-support-in-adfs/.

OAuth authentication and consumer secrets

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.

Resources