Open IDC OAUTH
lets say we have users and user interact with server
Server always interact with some kind of database
User send request to server on your server it just like a application [it can be JS, JAVA, Python]
It does some kind of operation on database [database can any thing, postgress, mongodb]
Db return response to server and server send result to user as per query
+------+ request +--------+ query +------+ | USER | ------------> | SERVER | ----------> | DB | | | | (app) | | | | | result | | data | | | USER | <------------ | SERVER | <---------- | DB | +------+ +--------+ +------+
Now this server basically act as proxy between user and Db [make a connection] and also do Application level processing this is basically what your backend does. for example do validation what you send the data is in correct form.
Make the transformation on it and most important it do Authentication because we cant give access everyone
Authentication process on server
Authentication has 2 types
Stateless (Token) all control at user and this is more scalable
Stateful (Sessions) always use - all control handle by backend
We can say its Symmetric Authentication
Vertical scaling - means adding more power (CPU, RAM, storage) to an existing single server to handle increased load, like upgrading from a smaller machine to a larger one.
Horizontal scaling - means adding more servers to your system (instead of upgrading one server), distributing the load across multiple machines.
When 1 server become bottle neck that time we do horizontal scrolling
using this approach we can drive user traffic to another server.
In Stateless auth when we create the JWT Token, we provide Token(payload and Secret Key)
Secrete key is very important concept, If secrete key has leaked anyone can create token using this secret key behalf of you.
In the symmetric authentication system you will provide the secret key to all horizontal scaled all server(3). As an environment variable you can give. All 3 server has copy of secret key
There is 2 problem if key has changed you have to make sure all server has updated key
Symmetric authentication means you have just a single key, this key is responsible for both
Assigning the token - if want to create toekn
decode the token - and verifying the token
All work is handling by single key we can say everything is symmetric authentication
This work is perfectly fine, no problem at all.
But the problem comes as soon as goes to scale, As soon as increase your verticals
What does mean by Monolith Architecture ?
You are keeping all products in 1 server
you create /auth /file-upload /ticket-booking
all these things upload on 1 server and deployed on it.
When my server overwhelming I will create multiple instance of sever deployed
This is monolith architecture every server can do all things
Same code has placed in each server.
What if there is a bug with file upload service my other server should work smoothly
But here due to an issue with file upload functionality server has crashed and impacted on other services /auth and ticket booking
Suppose in Twitter you do the file upload, lets say file upload not working, can we hold the exsting user to watch tweet - no
other activity will work smoothly, /tweet /commnet /like /Text tweet
Wheathr You have scaled the server due to monilitih architecture bug all server is down and services not running up
Another problem is I cant do independently scale each modules. If we think auth service is used lot rather then file upload, we cant scale file upload only, we had to scale by default all services instead of auth only
How can we solve this problem
Microservices Architecture
Can I do the make folder for auth and add express application on port 8000 and run all /authrntication routes /login /signup /forget-pass /verify-pass /profile
I will make the another folder /upload-services with express application on port 8082 and make 1 route /file-upload
Similarly I created another 1 server for /book-my-ticket with express application on port 8081 and keep the all /bookins-routes.
I will make 3 services and deployed it on different machine (server)
auth.jingalal.com
fileupload.jingalal.com
booking-service.jingalal.com
when user interact with auth will response the auth server
when you want to access the file upload the fileupload.jingalal.com is responsible to serve that service
Some how I fee that auth service server is overwhelming I can only increase the instances of auth.jingalal.com
not required to scale the other server and if there is an bug in fileupload.jingalal.com my other services will work smoothly
What is big issue with this microservices architecture
I create /auth-server and /booking-server
If User has logout, User which server will he approach for token.
User will approach to /auth-service with his {email, pass} for a timing /auth-service and /booking-serices has common database
/auth-service has 1 JWT_SECRET in environment variable he check if it is valid, server should release the token to user
Now user will go the booking server with his token. /booking-serices also required the JWT_SECRET to access the token So I will have to keep the JWT_SECRET copy at booking server also
Means I have to keep the secret every service /file-upload, /post
Here is problem
- If I want to change the secret every environment needs to change 2)There is more chances attacker hack the JWT_SECRET If i sent the .env at every services 3)Rotation problem - some time frame JWT_SECRET required the rotate token
I cant go for this approach, What is solution of this
- Common solution - what booking service can internally call to auth service ask to verify the token
Once verify by auth service will get the user object, Auth service send the object to booking service
That means this is done by middleware service and every service will a middleware service
1.Incoming Request
2.Make the API Network call to auth.jingalal.com to get the token info
3.next()
But here is big problem we have call network hop, added the network hop
Network hop means - you have to do additional api request to auth server. Latency increased. for every incoming request from user you have to make a call and come back request.
And after many request auth.jignala.com suffer the load doest matter user user access any service he had to visit auth.jingalal.com to verify (ghum phir ke auth.jingalal.com pe ayeaga)
auth.jingalal.com will be hot service
This is the exact problem, where can I keep centralise signed JWT_SECRET
If i didnt give it to all services, that service every time come back at me to JWT_SECRET who is user.
If I gave to all, Idealy it should not good practice. We will face the issue
Same problem happend with Google google run the many services
1.Gmail 2.Youtube 3.Drive 4.PlayStore 5.Map
You observer that when you reach at any google service. to signin there will simple common screen for every service.
That means google has central authentication service.
This service provide the token every one and verify also
This is common problem which face by big company, If you work on google cloude and Want to authenticate, can google give you the token to you ? No its very risk
This was a problem
All company sit at round table conference to solve this problem. Lets build something which everyone use.
They have decided to build A symmetric Authentication
We create 2 keys Public key (PRIVATE_KEY) Private key
we generate the user token always with PRIVATE_KEY
Token(payload, PRIVATE_KEY)
That means PRIVATE_KEY is something to safe authentication with us
Any one can verify the token using the PUBLIC_KEY
User Token + PUBLIC_KEY = you will get the user Object that means PUBLIC_KEY can carry to all services
Does the problem solve at small level
Using this PUBLIC_KEY user can only verfy (cant make any changes or cant do sing In, cant make a token)
Token can be make by PRIVATE_KEY only, while making token. To verify this token created the PUBLIC_KEY
PUBLIC_KEY we can distribute every where, if attacker has leak the key he can only see the content cant do change inside it.
Now /booking-service can verify the token using the PUBLIC_KEY
NOw question is 1.how to distribute the PUBLIC_KEY to publick
2.If some how I changed my PRIVATE_KEY, that time I require to tell every one where I distributed the PUBLIC_KEY
How can solve this problem?
Can we do In Authentication Service using express make get route
GET/ public-key and return res.json(PUBLIC_KEY)
All other service can access this route once
make a request for PUBLIC_KEY until the expiary (month or time period) after that fresh public key will received
before we used to on every request now we can do when it expired
In Round table conference finalized the A Symmetric Authentication approach
and how multiple microservices of the system will exchange user information between each other
Decided 2 standardization [2 ptotocol] OIDC - is the one used most common modern application and all of the company like google, Microsoft, its work on JSON format
SAML - work on xml its outdated
OIDC - Based on Authentication Service.
Decided the service discovery
service discovery - means standardize make the route BUT also it should be discoverable
Who is writing the Authenctication service will have to follow common the get route to every one
In this service discovery should return Json with authorization url.
whatever url is return in authorization json will server for login url
Service discovery:/.well-known/openid-configuration Return JSON {authorization_url:""}
If i want to know the login url of google I will visit "well-known/openid-configuration " and check the return JSON authorization_url
google auth service has https://accounts.google.com
can we check https://accounts.google.com:/.well-known/openid-configuration
and
http://auth0.oepnai.com/.well-known/openid-configuration
both are giving us same structure format
{ issuer: "https://accounts.google.com", authorization_endpoint: "https://accounts.google.com/o/oauth2/v2/auth", device_authorization_endpoint: "https://oauth2.googleapis.com/device/code", token_endpoint: "https://oauth2.googleapis.com/token", userinfo_endpoint: "https://openidconnect.googleapis.com/v1/userinfo", revocation_endpoint: "https://oauth2.googleapis.com/revoke", jwks_uri: "https://www.googleapis.com/oauth2/v3/certs",
response_types_supported: [ "code", "token", "id_token", "code token", "code id_token", "token id_token", "code token id_token", "none" ], response_modes_supported: [ "query", "fragment", "form_post" ], subject_types_supported: [ "public" ], id_token_signing_alg_values_supported: [ "RS256" ], scopes_supported: [ "openid", "email", "profile" ], token_endpoint_auth_methods_supported: [ "client_secret_post", "client_secret_basic" ], claims_supported: [ "aud", "email", "email_verified", "exp", "family_name", "given_name", "iat", "iss", "name", "picture", "sub" ],
1.issuer : base url 2.authorization_endpoint : This a place where you are going to your login page.
If I am making the openid client. can I ask to backend no I require only 1 URL "https://accounts.google.com:/.well-known/openid-configuration"
What my front page Will give the GET request on url "https://accounts.google.com:/.well-known/openid-configuration"
and extract the key "authorization_endpoint" for the value of login page url
What if I enter the url "https://accounts.google.com/o/oauth2/v2/auth" directly on browser, it gives me an error because I am not trusted source.
If you want to token information you need to call "token_endpoint"
for token validationton to verify user will get request on jwks_uri to access PUBLIC_KEY. PUBLIC_KEY its located at key : jwks_uri : value is PUBLIC_KEY
Once recived it will chache for future use
Also important - token payload standardization also decided under claims_supported key
this is all called your Service Discovery
expose your url .well-known/openid-configuration and tell us about your token public_url
aud : who issue this family name is your surname given name - first name iss: issuer url name
OIDC
Create express application
GET Route .well-known/openid-configuration Return JSON Response
Issuer <> authorization_endpoint: where can user assign the token
If user want token he can connect to the
OAUTH-2
When we tried to acces the url "https://accounts.google.com/o/oauth2/v2/auth"
we got error
Lets assume we can create the our own Authentication service but I have to make it secure
and every user have to give the usename email, pass, and do verify also
To make own authentication serice is not good idea
Can we say google have been made the secure authentication serice, why can I ask to google share the user data and
its more secure
User experience also good, he doesn't have to fill logn form username, password
I dont need to remember my user name password
its called as SSO Single Sign On
If i want to make the connection with google can I used OIDC, I know google use OIDC service
jingalal.com requested to google https://accounts.google.com/.well-known/openid-configuration
google recognized as this is service discovery request and responded it
And i took the authorization_endpoint and verified the user.
But google why share the his user information to jingalal.com. meanwhile he doenst recongnized the jigngalala.com
We cant do verify only on the authorization_endpoint google say i do not recognize you as a trusted sources I will not authenticate to user, thats why I am recievin the error
https://accounts.google.com/.well-known/openid-configuration
That means OIDC works on internal google service like youtube which is its own know services
OIDC is fully secure
Google want to accees his secure service to all users and solve this problem Introduce Oauth
OAUTH- before u use my OIDC let share the information at my dev console
1.Application Name 2.URL 3.Your Privacy 4.Your Term Condition 5.Where you used the my user data which you are accesing. 6.where is your application hosted 7.redirect uri - once user filled information correct, where can I redirect to user
Once verify the google all above details google shared the
CLIENT_ID CLIENT_SECRET to jingalala
Now jinglalal is trusted source for google
Now google ask to jinglala when you request to my authorization_url appen the CLIENT_ID with qury parameter
authorization_endpoint?CLIENT_ID=
Once the jingalala hits the authorization_endpoint?CLIENT_ID= google backend will verify the source
Conssent scrren will show that name from Jingala.com
Singn In
continue to Jingalala.com
once user signIn with google screen will redirect to
7.redirect uri = jinglal.com/api/
What if there provide the token with
jinglal.com/api/?tokem=user_Token
can be happend man in the middle attack, yes it s possible if i intercepted the network call, I got your google token and jinglala token
Now here is big problem how can shre the token in trusted secure way
Oauth2 says that cant share the token.
google share the short code which is valid next 1 minute only
Now user will share the SHORT_CODE to jingalala.com backend and jingalala.com backend will share the SHORT_CODE + CLIENT_SECRET to "token_endpoint: "https://oauth2.googleapis.com/token"," of google now google will verify that CLIENT_SECRET is same what I provided to jingalal.com
if Its true in return finally I will received the user token from google and same token I will keep in the user cookies
OAuth2 enables the external systems to trust your OIDC endpoints

