API Authorization with microservices - c#

I have a multi-tenant project which will be calling multiple microservices to perform specific tasks.
I want the microservices to understand which DB to play with from the request being sent as the microservices will be used by every tenant, however, tenants will have their own DB. I have another solution which has a Web project which deals with API key management.
Let's say for example the API key management is sitting on domain: portal.example.com
When tenant.example.com calls microservice at microservice.example.com I want some middleware to listen out for the request on the microservice side and get the APIKey from the request, validate it by checking the portal.example.com services and if the APIKey is valid, grab the tenant for this API key and determine the connection string to use for the microservice.
I feel as if this isn't efficient as it requires too many calls just to determine the connection string to use, can anyone think of a better method of determining a connection string but also validating an APIKey?

The nature of the issue seems to require some more information with regards to some business decisions and architectural decisions.
But with the information you've provided so far, I would say that the connection strings you're referring to could potentially be a problem for data leaks as well. Given that if there are errors in the authorization service that sends the wrong connection strings, you may accidentally connect your client to another database rather than the actual client that made the request. Second point to this is that it also makes the authorization service a single point of failure. If it fails or if a malicious user gets access to it, all your tenants are affected.
Instead of letting the architecture handle this, one thing that may be worth evaluating is to use OAuth's client credentials to authenticate different applications; each application reflects a different set of database parameters. During the OAuth authentication phase, it will redirect the user to the correct application. In summary, a single set of applications deployed for each tenants where tenants are authenticated via OAuth.
A slightly different alternative is to deploy and replicate the entire stack that you use for one tenant for another tenant with their respective database credentials. I would advocate for this only if you're limited by development resources.

Related

How to manage session across multiple APIs

I have a very basic question as I was watching few tutorials related to Microservices. If I am creating multiple microservices for 1 application, should I need to implement Authentication and Authorization for all microservices? For example If I have an e-commerce website and I have multiple microservices with certain endpoints for the purchase model.
As a user when I login to the UI, initially calling in AccountManagement microservice ( which has few functionality such Register/Login/Reset/Revoke) and then move from one feature to another which interim calls another microservice (should the next microservice read the cookie information and authenticate automatically ? Is that how it works?
Will my other microservices also have all features of the Account management microservice or only authenticating through Refresh token?
I am fairly new to this concept in microservices and trying to grasp as much as I can through tutorials but these questions are something I still struggle to understand properly.
Answer 1.
Token Based Authentication
It is always ok for you to build stateful application for monolith but not for stateless microservices. Session-based authentication works well for Monolith. However, for microservices since you need to route requests to multiple independent services. To maintain statelessness in our system, we opted to use token authentication. We packaged user claims in the jwt. Hence, we need Authentication for Microservice.
You can apply SSO based approach.
When a user logs in for the first time from any frontend app, a cookie called jwt-token gets created on the api-gateway. The cookie’s domain is .myorg.com and hence accessible to all myorg.com subdomain. When a request is made from any of the frontend apps to the api gateway, we extract the cookie named jwt-token if set. If not set, we assume the user is not logged in and return a 401-status code from the api-gateway.
If your microservices are not exposed to internet, you can also introduce basic authentication. This will also make sure reducing any security risks internal to your company.
Answer 2.
Microservice follow DDD (Domain Drive Design) Principle which makes them independent small application. You should not add any functionality of Account management (it is an independent Service). Other Service should have their authentication along with their domain which can be like Customer, Payment, Audit etc.
Refer These articles :
https://medium.com/technology-learning/how-we-solved-authentication-and-authorization-in-our-microservice-architecture-994539d1b6e6
https://medium.com/walmartglobaltech/building-domain-driven-microservices-af688aa1b1b8

How to Authorize request from another WebApi project

There are 2 WebApi Projects on different servers. One of these servers (WebApi-A) has OAuth2 authentication workflow setup with Authorization Server and all.
The another WebApi project (WebApi-B) has an end point that I would like to Authenticate through [Authorize] attribute. I don't want have a new authorization server but to utilize (WebApi-A's) authentication process just to validate the token.
From what I understand if the machine-key is same across these server. We can essentially replicate the authentication process from WebApi-A in WebApi-B without having to call WebApi-A at all.
How do I achieve this?
You could, in theory, pass through the JWT token and if your OAuth setup uses the same client secret and data store it should just work. You would have to ensure that you add the JTW token when requesting and to use some distributed cache to verify.
I would rather ask whether or not you should rather create a gateway that can handle and authenticate the requests and delegate them to the separate APIs? This feels like an identity server (http://docs.identityserver.io/en/latest/topics/apis.html) would solve your problem. Anything you do other than moving the authentication from web api A would just be a stopgap.
Duplicating the setup could work but that will mean that you have to now maintain it in two places. So I agree that doing that is less than ideal.
This is a great article that may aid you:
https://www.scottbrady91.com/OAuth/Delegation-Patterns-for-OAuth-20
This will have a lengthy answer so I will just leave you this diagram showing multiple Resource Server, Client, and a separate Authorization Server
Taken from this article Single sign-on across multiple applications (part II) which I hope could get you started.
you can use your token when login in web api and then you add the token to the header "Authorization" with bearer "your token"

Implement identity server authentication in real world scenario

I am investigating how IdentityServer 3 works and I still have problem to fully understand.
In general concept is clear to me but still I am not sure how to implement this on real project.
This is basic example that I am trying to implement in my case: link
I have web api project and I want to call my api methods from any client (mvc, wpf, phone…)
So I need implementation that is suitable for all clients.
If I understand well (and probably I am not understand completely), I should have 3 projects:
Client
Api
Project that host IdentityServer
And all projects should have required stuff like on picture:
Steps on picture:
Get token
Return token
Call api
Check if Token is OK
If Token is fine than return data else show error
My questions are:
Is my thinking about how this works ok?
Where I making mistakes?
Is this example good enough for my case? Am I missing something
important?
Do I have to create project that host IdentityServer, or this is
needed just for example code ?
Does IdentityServer host project must be console application that
communicate with api and client(like in example), or in real world
this is done differently ?
Should project that host identity server be aware of Clients and
Users ?
Should some other project except host identity server project be aware of Clients and Users ?
What is diference between implicit and hybrid flow, what I need in my case and why?
How do I create my own login view? I want have html page for login if I use web client, but to have wpf login view if I use wpf, also different view for mobile client.
EDIT:
I think that I need Resource Owner flow . I supose that resource i view where user type user name and password.
Your basic flow is correct, with Identity Server acting as your authorization server and your client and web API separate.
You should host Identity Server in its own project to ensure it is separate from any other logic which has the potential to introduce security concerns. How you host it is up to you and your use case. Typically you would see it hosted within an ASP.NET project on an IIS Server.
Identity Server must be aware of clients and users in order to authenticate them. The only other projects that should be aware of your identity store (users) is any applications that concern things like admin, user registration, etc. The client store would only ever be used by Identity Server.
Views can be modified using the Identity Server templates or by introducing your own ViewService. See the docs for more info: https://identityserver.github.io/Documentation/docsv2/advanced/customizingViews.html
Regarding flows, the Resource Owner flow is OAuth only, so there will be no authentication (log in page), only authorization (server to server).

Role-based authentification for the WCF REST service

I am trying to implement role-based authentification to the REST WCF service . I read a lot of information on this theme but didn't got a clear understanding of what I have to do.
I understand how to restrict an access to the service using the [PrincipalPermission] attribute but don't know how to check whether the user belong to the certain role or not.
Therefore I will be very grateful if somebody can direct me to the right way (e.g. make a roadmap what should I do to achive this goal).
Let me describe this situation. I have a remote services which hosted on the server A and ASP.Net MVC client hosted on the server B.
All of these rest services has an access to the database where I can read an information whether the user has access to the service or not.
OK, Tequila, IMO what you really want, based on your description, is a normal, REST WCF service with a Login(ID as string, PWD as string) method that (perhaps) returns a SessionID. This Login() or SessionID() check method would then preceed access to all of your other methods. And since it's a webHTTPBinding -- effectively a stateless web service -- you'll need to check the SessionID or ID/Password before each request is processed.
So the workflow would be something like this:
1) client sends Login() request to host
2) host checks ID/Password against DB, creates SessionID in DB that times out after x hours, forcing new Login(). SessionID is returned in response to client,.
3) In all subsequent requests, client must provide that SessionID. That SessionID would be checked on the DB, returning stored information about the client (Role, name, ID, address ... whatever is useful) before the remainder of the request is processed.
There are methods for authenticating users BEFORE the request gets to your working code (like client authentication using Forms or client certificates (see http://msdn.microsoft.com/en-us/library/ff405740.aspx)). This shifts the Login() / SessionID check to a method executed BEFORE the request hits your main program, but the steps are basically the same.
And since passing ID/Pwd in clear text over the web is a no-no, you'd want to implement SSL on your web service (see http://msdn.microsoft.com/en-us/library/ff650785.aspx)
Everything I've describe is basically platform independent, so if you'll have iOS or Android clients, there's nothing in what I've described that would prohibit those OSs from successfully interacting with your web service.
Good luck.

WCF authentication service

I am relatively new to the WCF world so my applogies for the newbie question. I am currently designing a layer of WCF services. One of them is an authentication service, so I came up with the following authentication mechanism:
IUserService.TryAuthenticateUser(string username, string password, out string key)
Basicly the user tries to authenticate and if successful - he/she receives a sessionkey/securitykey/whateverkey... the key is then required for every other "WCF action" e.g.
IService.GiveMeMyFeatures(string key);
IService.Method1(string key);
This mechanism looks extremely intuitive for me and is also very easy to implement, so what bothers me is why I cant find similar WCF examples? This unique key (which is practically a session key with wcf-side expiration and all) can then by used from the various applications, according to the application's architecture: for ASP.NEt it can be stored in a cookie, for Winform/WPF/Mobile I guess it can be stored in the form-class in a field and so on...
So here comes question number 1: What do you think of this method?
I also read, that I can use the build-in ASP.NET Authentication Services (with membership providers etc... if I understood correctly). From architecture point of view I dont really like this method, because when authenticating from an ASP.NET page the workflow will be like this:
ASP.NET -> WCF -> ASP.NET Authentication Service -> Response
In this scenario one could also bypass the WCF layer and call the auth. service methods directly from the asp.net page. I know that by going thru the WCF layer for every authentication request I will lose some performance, but it is important for me to have a nice, layered architecture...
And here is question number 2: What are the advantages/disadvantages of this method over the first one, and why is it so popular, when from architecture point of view it is kinda wrong?
I also read, that I can send user credentials for every WCF method call and use the built-in mechanism to authenticate and respond properly to the request.
Q3: What do you think if this method?
And to sum up - obviously there are many authentication methods, but which one do you think is best and most generic (considering that the WCF services will be called from asp.net/wpf/mobile/etc...)?
Thanks is advance :)
The reason you can't find examples it's not best practice - it's turning something that should be stateless, web services, into something stateful, and something that will not load balance well at all.
As web services already have standard username and password facilities, supported by almost every SOAP stack (excluding Silverlight) that's the way to go. You can use the standard .NET role based security model to protect your methods with this approach as well.

Categories