I have a REST api( nodejs+express+mongo) that is being consumed by two types of users:
End-user (Authenticated via website, mobile apps using google-signin).
Gateways/services that will consume the API programmatically.
My question is about what is the best way to handle authentication for the second type of user ?
The users are stored in my database(linked to google-signin using their email-id)
The end-user creates gateways and services so I could provide an interface to manage credentials for that.(For example if I use API Keys or public-private key pair, then the user could use the website to add/remove credentials for gateways/services).
I am using passport-google-oauth2 Strategy to handle authentication for the first case. What would be the best way to handle authentication for the second type of consumer ?
Firstly, OAuth is an authorization protocol, not an authentication protocol. Google authentication is performed within a web login session, so I'm not clear how that would work for you in conjunction with a REST client.
Unfortunately there are many ways you could approach your problem, depending on how much code you want to write vs how many existing services you want to use instead and how you intend to do your user management.
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'm developing a bunch of APIs that will have both internal and external (to the company) consumers. I'm using AzureAD for authentication. Whilst these consumers will be integrations written in code, I don't want to have to create and manage dedicated "app registrations" for each client/consumer. I also want to be able to use roles for more granular permissions.
It feels like a long-lived refresh token is the best option for this, and I've written a working proof-of-concept for this, which meets the requirements perfectly.
Given this is security though - I wanted to ask if I'm doing anything stupid or wrong.
First question - is it okay to treat a refresh token as a long-lived secret that consumers can store in their secure config, then their systems programmatically use that to query an access token to use against our APIs?
If this is okay - my second question is regarding the client id and secret. Because the implicit flow doesn't support refresh tokens, I'm using the authorisation code-flow. For this, it looks like I have to pass the client-id and client-secret as well as the authorisation code or refresh token to AzureAD. This means that I need to create a dedicated "auth api" that the consumers call to request these tokens. This auth api literally just then makes a downstream call to AzureAD passing the clientid and secret (which the consumer obviously doesn't know about). It feels like if the implicit flow supported refresh tokens I wouldn't have to implement this "auth API" at all. But because I have to use the authorisation code flow - it's forcing me to implement a proxy "auth api" for all token requests to go through. Am I missing something - or is this the way I should be doing it? It's fine if so - as this is what my PoC is doing, and it's working. But again, just wanted a sanity check on this with it being security related.
Ps. I know Azure API Management gives a lot of this functionality - but for reasons out of scope of this question, this isn't a good fit for us.
Update
To add another couple of reasons why this method fits my use-case really well...
A lot of internal developers will also be using these APIs (internal to the company). They already have AzureAd accounts anyway. So this then becomes super-simple to manage - we just have a bunch of security groups with certain roles in the app registration, and we can just add devs to those groups. And they don't need to know the client id / secret - they just use their own user account.
The APIs have Swagger UIs. Using users instead of clientid/secret - means developers can use the Swagger UIs with single sign on.
WEB CLIENTS
So a web app is used by developers to sign in via their Azure AD account. Authorization Code Flow is fine, after which each user will get access tokens and refresh tokens for calling APIs. Tokens will include the user's role and APIs can use them for authorization.
EXTERNAL API CLIENTS
These might be B2B clients and therefore use the Client Credentials Flow. Tokens issued to these clients would then have no user context.
INTERNAL API CLIENTS
It is a little unusual for a developer to login to a web client and then take tokens issued and use them in other apps. This is partly about reliability and partly because different apps generally access different areas of data. See this scopes article for details on designing how components call each other.
REFRESH TOKENS
A refresh token is something that will expire so you need a plan for this. Avoid using them in static configuration. Consumers need to handle refresh token expiry in order for their app to be reliable.
CODED INTEGRATIONS
Are these web clients or APIs, and how many distinct apps are there? It feels like combining these into one or a few client registrations is the right option. A common setup might work like this:
All developers might share the same registration
All web clients use the Authorization Code Flow - and you Auth API
API clients forward tokens to other APIs, to maintain user context
I was already know azure functions have two types of hosting ,
Server Less
On- premises
But What i need to know is , Can i store My Login token to server less Azure functions ?
I have this doubt so i am not tried any thing i searched lot of things in google , But i am get clarification.
I need server less azure functions API 's can support session maintenance or not?
Any alternative solutions is there to store my token ? Call other Authorized API's ?
Azure Functions are Stateless
If you're wanting to store a session with data against it, you may want to take a look at something like Azure Redis Cache, you'll be able to get/set session data from Redis inside your functions.
Azure Functions offers an alternative for creating stateful functions called Durable Functions. Durable Functions is an extension to the Azure Functions runtime that enables the definition of stateful workflows in code.
For more information follow the below docs.
https://learn.microsoft.com/en-us/dotnet/standard/serverless-architecture/durable-azure-functions
https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-overview
Yes Azure functions support session storage in this way. If you need to authenticate a user you will need some mechanism of doing that.
So for example if you're token exchange mechanism is AAD or B2C or a social like Facebook or Google or an open id connect authentication mechanism they would all be the mechanisms to authenticate/authorize a user and obtain a token and then store that as a user session.
An Azure function can certainly be apart of that process.
App services and functions use what is called "Easy Auth" or AuthZ middleware type functionality for handling incoming requests.
The authentication and authorization middleware component is a feature of the platform that runs on the same VM as your application. When it's enabled, every incoming HTTP request passes through it before being handled by your application.
The platform middleware handles several things for your app:
Authenticates users and clients with the specified identity provider(s)
Validates, stores, and refreshes OAuth tokens issued by the configured identity provider(s)
Manages the authenticated session
Injects identity information into HTTP request headers
Calls from a trusted browser app in App Service to another REST API in App Service or Azure Functions can be authenticated using the server-directed flow. For more information, see Customize sign-ins and sign-outs.
So all in all, yes, there is a way to have a user session with azure functions. Now if you were comparing to express.js or fastify or asp.net you're not going to get the fine grained control as you may want on the call level. But it would be there on the IDP (identity provider level.)
So, if you were to define roles access and other things you could do that all through your IDP situation and then the token upon request would check your token to see if it were still valid and or see if you had to re-sign in.
As someone mentioned the primary driver of the session isn't from the api really but rather the client login. This would just be an extension of that client user journey. i.e. did you already do it if not you need to. SSO and other things regarding user session and auth come into those factors as well.
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/.
I'm a bit confused about how to properly and securely authenticate users using my REST API and provide and option to authenticate using other OAuth 2.0 providers as well (e.g. Facebook, Google, etc.).
Scenario
Users interact with a web application which should consume my REST API. Users should be able to login and perform CRUD operations both using username/password and by using 3rd party services such as Facebook. I will be using SSL to encrypt the traffic to the website and the API.
Without taking the 3rd party login services in consideration and by studying the various questions already asked here on SO, I thought about handling user authentication as in the picture.
Technologies and current idea
The REST API is written using JS using NodeJS and Express. The WebApp provided through another NodeJS instance is mostly AngularJS with templates which consumes the REST API.
My current idea is to let the WebApp handle the login sequence and let Facebook save their token in my DB using the callback. But this solution smells too much of workaround!
Questions
Is the authentication sequence depicted in the image correct?
How is the above authentication sequence compared to the Resource Owner Password Credential flow in OAuth2.0? Is it worth using OAuth2.0 instead of it?
How can I integrate login through 3rd parties (i.e. Facebook)? Any suggestion or (better) example?
References
passport.js RESTful auth
Login with facebook and using oauth 2.0 for authentication of REST api calls
And many others here on SO :)
My 2 cents..
The process looks good to me.. I would re-issue the token on each sign in and also keep it inside a database so tokens can be revoked easily.
Use PassportJS. Its got support for OAuth flows and supports many 3rd party integrations like FB, Twitter, Github etc..and since its a nodejs middleware.. its integration will be very tight within your application..