I'm very new to Microservices, and I would like to model something simple on paper: An application that allows users to login and upload photos (for sake of example).
I assume I would need:
Login service
User service
Pictures service
Can anyone assist with describing what the APIs would look like?
Login Service:
(POST) Login?user=username&pwd=password - Logs a user in
User Service:
(GET) User&user_id=123 - Gets the specified user
(POST) User - Creates new user
(POST) User&user_id=123&name=John - Updates existing user
How would a delete look like in this example
Of course, the photos would follow similar suit to the User Service.
However, I'm having a difficult time understanding how, say, the Login service will be used? Does this mean we have to call the login service every time that we need to authenticate a user? Or what would the general interaction be?
Thanks for any insight
For securing APIs the de facto approach is to do something like this:-
Authentication
Authenticating a user usually happens once per session - where session generally refers to a period of time in which the user is automatically logged out if the client is inactive for a specified period.
For example, if using Enterprise Java, you would usually configure your application server to timeout the HttpSession within a certain period of inactivity. You would authenticate the user - usually by comparing basic authentication credentials (username/password) against some profile you stored for them after they registered (using some Registration service). As part of authenticating a user, a HttpSession would be created and the user's ROLE is stored and checked on each request to check if the session is still valid. If the session has timed out, then the user needs to be directed to the authentication service again.
If using a stateless framework (no session hanging around between requests) then you would usually pass some token back and forth for each request and have some sort of validation mechanism ie. user profile stored in cache.
Think of authentication as ONCE PER SESSION.
Authorization
For each request (assuming the session is still valid) you would check that the user's ROLE has the necessary privileges to carry out the action requested.
OAuth - an example of an Authorization framework) - is generally designed for authenticating third-party clients to access one of your user's resources but if you have a look at OAuth 2 then it will give you an understanding of the token-based approach at authenticating a user/client between requests.
Think of authorization as EVERY REQUEST.
Related
I have the following projects:
Identity Server 4, with ASP.NET Identity as a user store for all users of all my apps.
.NET Core 5 Web API
Xamarin app
The flow goes like this:
User logins from the Xamarin app (3) and is authenticated against IdentityServer (1)
User receives an access token from Identity Server, that contains the sub claim
User makes a request to the Web API (2) using the access token
The Web API (2) checks its own database for user permissions
----QUESTION/PROBLEM IS HERE-----
Should the Web API add these user claims (permissions) to the access token, OR should the Web API always check the database for the user permissions on every request made from the client?
Maybe I could add the claims before authenticating with IdentityServer, but this would mean that IdentityServer would have access to the Web API's database. I believe this is not a good practice because of separation of concerns.
Another solution would be to introduce a caching mechanism when the Web API validates the token, so that it doesn't always check the database.
Using claims transformation, it is my understanding that I can add the claims to this 1 request only, meaning that the next time a client makes a request, claims transformation should happen again, since it doesn't return a new access token to the user.
Ideally, I would like the Web API to add the claims to the access token so that the Web API can trust these claims on all subsequent requests. I cannot find a way to do so, though. I've searched for Claims Transformation, IssueJwtAsync (IdentityServerTools), IProfileService, but I think none of these are solutions to this problem.
Is this good architecture? Please do share your opinions on this subject and potential solutions.
Thank you very much!
You need to add these permissions in web api, because users need to access the corresponding resources according to these granted permissions. And permissions are granted when the user logs in for the first time, without the need to access the database in every request.
In this case, you can use Claims Transformation. This link has more detailed steps which can solve this problem.
We are looking to implement a Micro Services architecture in the future. We don't want permissions at the API gateway to be very clunky and restricted to GET, PUT, POST etc.
We want granular application permissions to be stored and managed centrally, so apps only have to fetch them and not manage them.
I have included a picture of the draft architecture I have in my head as well as logic flow below.
My Question
Can this design pattern be implemented using any of the existing authentication/authorisation specifications such as OAuth2? If not, is it acceptable to create your own Authentication / Authorisation pattern for use with in a private network?
App Life cycle
A developer creates WebApp1
WebApp1 is registered in the Web App Registry Server by the developer. He/She also registers the custom permissions that the App exposes.
Users can have access granted or revoked to the granular permissions exposed by the App by an IT Administrator.
In the example above WebApp1 exposes two permissions CreatePost & DeletePost user1 only has permission to CreatePost
User Process Flow
An unauthenticated user accesses WebApp1 and is redirect to the Login screen.
The user's credentials are validated against LDAP and a UUID Authorisation token is generated. The token is stored in a Security Token Server and the user redirected back to WebApp1 with the token included in an Authorization Header.
WebApp1 requests the permissions this user has from the Web App Registry server, this can be done every x minutes and stores them in local state. The Web App Registry Server also checks the Authorization token is still valid.
WebApp1 checks every x minutes that the users token is still valid, if not the user is requested to login again (or a refresh token could be included with the original token that was sent to the app when the user Authenticated).
Interesting question - some thoughts below on achieving your goals via OAuth based design patterns:
AUTHORIZATION GOAL
The desired end state is usually to give yourself choices:
Use a pattern that enables any API component to do authorization
Sometimes you need to be close to the data source to enforce permissions.
Other times you may want some types of rule to be enforced via a dedicated service
MAPPING TOKENS TO PERMISSIONS
I like this way of doing things. In effect it is a Claims Based Architecture, and the information you need for authorization won't come solely from tokens.
My API Authorization Post describes an extensible pattern that starts with defining a claims / principal object in each API. Here is some sample code, where the Authorizer class provides an overview of behaviour on each API request.
WEB APP REGISTRY
I would be careful about creating components that could come under heavy load and become a bottleneck for your whole software platform - should you need one of these?
CLAIMS AND MICROSERVICES
A pattern that can work well is to design 2 levels of API. Interestingly, both of these can use claims and you can put authorization responsibilities anywhere you want - and give yourself choices:
Entry point APIs: exposed to the internet, do OAuth validation and naturally lock down what clients can do with access tokens:
Microservices: run in a locked down network and can freely call each other without OAuth plumbing
My API Platform Architecture
post explores this option, where claims are passed between microservices via headers.
ACCESS TOKEN VALIDITY
You can often simplify code by following the below rules, since there can be multiple reasons for tokens becoming invalid:
Keep access tokens short lived ~60 minutes
Handle 401 errors in the client as in this code
After having read books and watched videos on OAuth, OIDC, PKCE, JWT, etc. I still have no idea on how to use all of these for my app (a secured REST API).
My use case is fairly simple. I want my users to be able to login with Google, Amazon, Okta or whatever and the only info I want from them is the email address they used to login, nothing else. After their first login, their email will be added to a database and in a separate process I will grant them some permissions (what resources they can access).
So let's imagine a standard authorization code flow and let's fast forward to the access token part. The redirect URI has been called, we are in my client (somewhere is my backend/API) where I retrieve an access token. At this point the user has been successfully authenticated.
But what now ?
I don't care about Google anymore (do I still need the access token ?), but I still want to check if the user can use my API for each request and is able to access the API resources depending on his permissions.
How do I keep the user authenticated (for like 2h only) and check his permissions ? A session Cookie, a Token or something else with an expiration time ?
Do I need my own authorization server to check if the user has access to the resource he is requesting ?
Considering my requirements, do I need PKCE if the API is accessed from an SPA or a mobile app ? Wouldn't the authorization code flow be enough - the SPA or mobile app retrieve an authorization code, then call the callback endpoint from the API ?
And the more important question is, do I ask the right questions or am I completely off track and it's not how it's supposed to work ?
In terms of your questions:
Your API needs an access token on every request
A stateless session is managed by sending the access token on every request
It is recommended to use your own Authorization Server that manages redirecting to social providers - this will simplify your UIs and APIs which only need to handle one type of token - also this means you are in control of the tokens your apps use
Yes - use PKCE for public clients - the Authorization Server and UI security libraries will handle this for you
Your use case is not simple at all on a technical level and requires a lot of understanding. A good starting point is to understand these aspects:
Role of UI and what a coded solution looks like
Role of Authorization Server and its configuration
Role of API and what a coded solution looks like
Open Id Connect messages used
These links of mine may be useful for browsing:
Initial code sample and tutorial
Message Workflow including PKCE
Given an access token, both the UI and API can potentially get the email via step 12 in the second link to lookup user info.
I am designing a service oriented application where the communication to the database is distributed across multiple services (Authentication service, some service for auditing and other for accessing the db and doing CRUD operation ... etc).
Say a user login to the app using his id and password, the app then talk to the auth service and find out if the information are correct, once done the user want to insert some data, now the app use another service to fulfil the user request. How can the other service now that the user is an authorized user to use the service.
Your use-case seems very similar to what SAML addresses.
Also look at OAuth.
If these standard mechanisms don't work for you, you can at least develop a mechanism where:
The authentication service returns a token on successful login. The
caller app should then be able to use this token to access the data
service and other services.
The data service should be able to independently validate the token (possibly with the authentication service).
You might want to ensure that the tokens remain valid only for a certain duration or certain number of invocations
What this avoids is the need for every back-end service to allow access to the app without using your login details.
Also see: What is token based authentication?
i am looking to build a client to my RESTful hypermedia based API and after reviewing many options am learning towards oAuth* to become the de facto method for authorizing access to the API.
I think i am understanding the overall oauth concepts, i.e. depending on the client (trusted or not) the spec provides several flows in order to "trust" the client (application) from the perspective of the resource owner (user) granting access to the client.
Becuase the application i am building is directly part of the ecosystem of the service it will fall under the umbrella of the trusted clients section so i have decided to implement the Resource Owners Passwords Credentials Grant but here is where my knowledge gets muddied with the terms and the exact role oAuth is there to provide and my brain shuts off :)
I am thinking this is the flow (with some more technical thoughts):
Via a login form the resource owner supplies their credentials
the details are posed to a server (in this case an express.js app)
the app via some local mechanisms authenticates the user credentials against a store
if the user doesn't exist or fails validation then they are returned to the login
if the user does exists and does pass validation the mechanisms to swap their credentials for a token is started (contacting a oAuth server and swapping the details) which stores the encrypted/hashed infor somewhere (redis maybe?)
Once the token is returned it is stored in maybe a session for persistence to the client (i think trello.com do something similar as they have a token cookie but i could be very wrong here)
Is this an acceptable flow? i can't seem to find any examples available and as a sole developer currently would be good to get some feedback.
No need in the end to define my own flow, this is simply the Resource Owner Password Grant where we exchanged the credentials of the user for a oAuth Token for trusted clients.