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
Related
Since IdentityServer's object is to provide authentication and authorization via implementing OIDC and OAuth2 it makes sense to me that user management (CRUD operations) is done separately, maybe in it's own assembly (these seem like two different concerns).
In a production scenario how do you go about separating these two concerns? I see two general options here:
There is a separate identity proverider (ASP.NET Identity Core) project/solution that exposes an API to create, update and delete user entities within its storage. IdentityServer calls this API when authenticating a user.
The user CRUD action endpoints reside within IdentityServer's host project. IdentityServer has direct access to the DbContext of the identity provider's database and implements all necessary user management operations.
The second approach is obviously the easier to implement, but I think that could mean uneccesary redeployments of the auth server if there are functionality changes regarding to the CRUD user operations.
Also what about functionality like forgotten password, email validation and so on. Where is the proper place for it? With IdentityServer or with the separate IdentityProvider (and IdentityServer calling its API).
I've seen a couple of StackOverflow questions in regard to this, but nowhere could I find a sound sample or good reasoning, everything was vaguely described.
P.S The IdentityProvider will be ASP.NET Identity Core
I'm working on building a series of micro-services using Aspnet Core. A mobile application, desktop application and web-application will consume the services over Http REST APIs.
For user auth, I'm utilizing the Aspnet Core Identity platform, but I'm exposing the creation of user accounts via a REST API. The clients make a REST call with the credential information and my API uses the Microsoft Identity APIs to provision the user. The user would be authorized to hit the individual resource servers with an auth server using IdentityServer4.
I have two questions that I've not been able to find clear guidance on from a security stand-point. Should the Aspnet Core project that utilizes Microsoft Identity for user creation be in an independent Aspnet Core project from the project that handles auth via IdentityServer4? Are there downsides do separating the two out that I need to consider?
The Microsoft Identity API has template and Razor Views that can be used to handle the auth from a server-side perspective, including redirects on account creation or sign-in etc. If I'm doing everything via SPA or Client-side native apps, is there anything wrong with just providing a POST API that accepts the user information, creates the account via UserManager<T> and returns the UserId?
I want to provide a dedicated sign-in page, similar to FB/Google/Twitter etc for Auth to happen across any app that wants to authorize a user for my services. I don't typically see account creation as part of the OAuth process though. Is it typical that you would allow for redirects to an account creation page, that redirects back to a client upon successful account creation or is that process typically just used for Auth via OAuth flows?
I would suggest to consider using one service for IDS4 and ASP.NET Identity since they can be integrated and give you the full functionality you're looking for(auth, and users management).
IDS4 has examples and good documentations regarding that.
To me, I think separating them would be an over engineering.
one example: when IDS4 generate access token for a user, you should get claims, roles and validate username and password, all of that are stored in ASP.NET Identity.
So for more details you can check the docs of Identity Server 4: http://docs.identityserver.io/en/latest/quickstarts/0_overview.html
or it's my pleasure to check my little blog post that I tried to give some more detailed and step by step.
https://feras.blog/how-to-use-asp-net-identity-and-identityserver4-in-your-solution/
Start with IDS4 link because it might be enough :)
The main point when thinking about security management UI is how to secure that UI. And the most safe approach for today is cookie-based auth with same-site cookie (the way, MVC uses by default). Consider that when and if selecting serverless SPA pattern. For management purposes-app having strict backend is much more secure than token-based access to distributed api-s.
Regarding the application hosting, #VidmantasBlazevicius is absolutely right, there is no the only strategy: hosting all the services in one app is simpler, so it better fit lo to middle loaded systems. But with raise of the number of users and authentication requests, you might want to scale, and separating management UI from authentication is one of the ways to handle that.
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.
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).
I am hoping someone can clear up how these things can work together.
I want to be my own identity provider, so in my web api I have an OAuth token provider. I want users to register with me and then be authenticated using my token provider. The idea in the future is that more of my mobile apps and web apps will be accessible using the OAuth login sharing the user's identity.
So, if I use azure mobile services how do I implement the normal asp.net identity stuff?
And, how would a normal web app be able to use the data stored in azure mobile services? Would I have two dbcontexts one for mobile and one for web?
I've been reading and watching a lot of stuff on azure but nothing seems to show how I can do this. Most of it has to do with using external providers like facebook, ms, twitter, etc. I want to be one of those external providers, just not sure how to do it and allow my websites to still use the .net identity data.
If you could point me to or post some example / tutorial / blogs that would be great.
This is a supported scenario, although it isn't documented very well at the moment.
The Mobile Services .NET runtime is built on the ASP.NET Katana authentication middleware. The mobile service abstracts these middleware using the LoginProvider base class. The authentication model was recently made extensible for situations such as yours. In order to have Mobile Services recognize and use your identity provider, you would have to create your own LoginProvider.
There are currently two examples of this:
Adding a Katana middleware as an identity provider - part of this post.
Creating a custom username/password setup - tutorial here.
You could certainly use these techniques to wrap the standard ASP.NET identity functionality.
As to your question about accessing the data, there are a variety of approaches. Your web app could treat Mobile Services as a backend and pass through requests. This is basically treating the web app as an additional client platform, peer to your mobile apps. Another option is to, as you said, create multiple DBContexts. While you might get slightly better performance, this comes with a code maintainability tradeoff. It also wouldn't scale well if you build multiple web apps on the same data backend.