I' new in implementing a RESTful web service. I need your opinion to understand if my idea can work. I want take separate the authentication database from the resources database (the main one, with all the user stories). I put them in two different web servers. The clients ask their token to this primary interface (the auth server) that replies the generated token (if login is valid) and at the same time the authentication server sends the userID and userToken to the resources database server.
The client has received the token, it means it's logged in and it can makes requestes of resources to the resources database server. It appends its userToken to prove its identity. The resources database server checks the userToken and if it's not expired, it replies with the requested data to the client.
I've tried to explain the concept with two images.
I would like to understand if this is a good implementation of an authentication process. I really care about the security, performance and flexibility. What do you think about this?
Do you have any suggestions related on this? Thank you very much.
Related
I'm planning to make a microservices architecture using Laravel as the backend and VueJs or maybe ReactJs as the frontend. The microservices will consist of
User authentication service (For authenticating user)
User management service (To manage organization member database)
Event management service (For creating organization event)
Etc.
All of the services will require user request to be authenticated, but using central user database, which is located on User authentication service. Eventually, on each web application, it will use at least 2 of the services.
How am I able to authenticate the user before making the request to the specified services? Thanks in advance!
Think carefully about your reasoning for developing a distributed system with a microservice architecure. Developing such a system can be complicated and might introduce more problems than it solves for you. You should consider things like code base management, data synchronisation and service availability for example. A standard monolithic architecture with the frontend (Vue/React) and backend (API) as separate projects will be simpler and may provide the flexability you need. Should the need arise in the future to develop a service orientated architecture arise, worry about it then.
That said, typically you wouldn't allow direct access to your services. There would be an API gateway which users access and it proxies requests to the relevant service. So your users would make a request to api.domain.tld/auth/login which would then be forwarded by the gateway to your auth service, process the request and then provide a failure response, or a success response which would include some sort of auth token which would be used to authorise subsequent requests to your other services. Sometimes services are aware of each other and can communicate directly if require, other times they use the API gateway for service communication.
Hello fellow programmers.
I hope there are some keycloak experts out there that can help me to solve my question.
So my situation is that we have microservice platform with ~20 services which in the future should be secured using keycloak jwt tokens.
The idea is that we offer an interface for our clients where they can register themselves with a password/key pair within one realm and they should be able to use that account to access all the
services through a public facade/api.
Now to the question - how to handle the client id - in all examples each service has its own specific client id - should this in our case be the client id of the public api//facade which allows the inner services or is there better approach how to handle this without forcing the user to log in for each service...
Thanks in advance for all help and I hope you are all doing well...
Gerrit
P.s. Maybe to clarify my question further - my current understanding is that for each. service i should add a new client to my realm but my users then would need to get a token for each service/client as each client owns his own secret... and I want my users to be able to use one token for all our services.
So after wrapping my head around this issue and reading the docs:
clients
Clients are entities that can request Keycloak to authenticate a user. Most often, clients are applications and services that want to use Keycloak to secure themselves and provide a single sign-on solution. Clients can also be entities that just want to request identity information or an access token so that they can securely invoke other services on the network that are secured by Keycloak.
I think to use one client for my user accounts for the whole platform is the proper way to go.
Would be perfect if one of the keycloak experts can acknowledge this.
I'm trying to figure out how to migrate a system that is currently using ACS to Azure AD. I've read the migration docs provided by Azure and have looked through the Azure AD docs and the sample code but I'm still a bit lost as to what the best approach for my situation would be.
I've got a web API that has about 100 separate external systems that connect to it on a regular basis. We add a new connections approximately once a week. These external systems are not users--these are applications that are integrated with my application via my web API.
Currently each external system has an ACS service identity / password which they use to obtain a token which we then use to authenticate. Obviously this system is going away as of November 7.
All of the Azure AD documentation I've read so far indicates that, when I migrate, I should set up each of my existing clients as an "application registration" in Azure AD. The upshot of this is that each client, instead of connecting to me using a username and password, will have to connect using an application ID (which is always a GUID), an encrypted password, and a "resource" which seems to be the same as an audience URL from what I can see. This in itself is cumbersome but not that bad.
Then, implementing the authorization piece in my web API is deceptively simple. It looks like, fundamentally, all I need to do is include the properly configured [Authorize] attribute in my ApiController. But the trick is in getting it to be properly configured.
From what I can see in all the examples out there, I need to hard-code the unique Audience URL for every single client that might possibly connect to my API into my startup code somewhere, and that really does not seem reasonable to me so I can only assume that I must be missing something. Do I really need to recompile my code and do a new deployment every time a new external system wants to connect to my API?
Can anyone out there provide a bit of guidance?
Thanks.
You have misunderstood how the audience URI works.
It is not your client's URI, it is your API's URI.
When the clients request a token using Client Credentials flow (client id + secret), they all must use your API's App ID URI as the resource.
That will then be the audience in the token.
Your API only needs to check the token contains its App ID URI as the audience.
Though I want to also mention that if you want to do this a step better, you should define at least one application permission in your API's manifest. You can check my article on adding permissions.
Then your API should also check that the access token contains something like:
"roles": [
"your-permission-value"
]
It makes the security a bit better since any client app with an id + secret can get an access token for any API in that Azure AD tenant.
But with application permissions, you can require that a permission must be explicitly assigned for a client to be able to call your API.
It would make the migration a tad more cumbersome of course, since you'd have to require this app permission + grant it to all of the clients.
All of that can be automated with PowerShell though.
I am currently building a microservices based application in spring boot with the following services
Auth server (Distributes access tokens)
User service (User info like username, password, email, etc.)
Various other unrelated services
When a user sends their credentials to the auth server, the auth server should verify that they are correct and then return an access token.
My question is, should I combine the auth server with the user service so looking up credentials is a simple database call, or should I keep them as separate applications and have them both point to the same shared database? Is there a better alternative?
What I usually do is keep them separate. Account information (first name, last name, contact data, affiliation, sex etc) is not related to authentication/authorization. Also, an account can have multiple authentication methods (i.e. OAuth, uname-pass, private key), which isn't really related to account data. So, I take them as separate entities. I know auth and account data seem the same, but they represent two very different things, with very different responsibilities, so I keep them separate. If one user should have to see some other user's first and last name, I wouldn't like to get other user's credentials out of the database (a lot can go wrong).
If you are thinking of UserService from Spring Security, it goes with Auth server.
From security stand point, having a single point of truth (auth server) and be able to fix an issue in one place is a huge advantage.
Anyhow, IMHO, account and auth can share some properties, but they are two different things - hence I keep them separate.
Hope this helps.
You should keep them separated, oauth is not related to identity management but to authorization delegation.
In oauth2 there are 4 roles (resource server, resource owner, client and authorization server) you are currently asking if the authorization server must be part of one microservice of the resource server which has absolutely no sense.
If I correctly got your case what you name a user corresponds to the resource owner role in oauth2 terminology, some oauth2 flows (e.g. client_credentials) directly allow a client to get an access to the resource server and there will be no users implied in any way.
Why sharing session to implement SSO is not good? I'm learning SSO system.
Thinking about this scenes:
Assume that all http requests to business services is required Login, the business services need verify the requests is login or not by asking SSO service in CAS or SAML. If there are 10 business services, and each service's request is 1k req/s, so the SSO service's request is 10k req/s. It's hard to image the SSO service can hold on.
SO, may be there is a cache mechanism in the business services to verify login token. But when user logout, the SSO service need remove the verify info, and the business services need remove the cache verify info also. I think that's too complicated. The SSO service need tell the business services some people was logout. So why don't all service sharing the login token verify info? Let SSO service write, and other business read. It remind me the sharing the session to implement SSO. And I thought if I can sharing the login token verify info by redis distributed cluster. But I have hear sharing session is not good? So why?
Whether the SSO server can handle that many requests depends on your deployment of it. There are very large deployments of CAS that handle hundreds of thousands of requests. It varies.
In general, the SSO session is entirely separate from your application session. Once you have logged onto the application via SSO, you have established a session for that application that will last for as long as you configure it to last. When it expires, your application may decide to authenticate against your SSO server again. If the SSO server has still an SSO session, it will simply re-issue the appropriate data and your app will recreate the session. If not, it will challenge the user for credentials, whatever they may, and redo the same.
Session concerns of the application are entirely yours and application's concerns. The SSO server should never get involved. If your application has a requirement to share sessions because it's clustered, then you should share sessions. Nobody said it's a bad idea. However, you generally want to make sure your application is as stateless as possible since that will make clustered deployments easier.
When you log out from your application, your app session is gone, but the SSO session may still exist. As a result, you will get right back into the app because there is no need to provide credentials. If you wish, you could log out of the app AND your SSO server.
If you have all other applications logged in via SSO, and you wish to log out of all by logging out of one, this is called SLO. Your SSO server will need to reach out to every app that it has created a ticket for and contact them to logout. Or, you could destroy the shared sessions for all apps assuming they are all part of the same suite.