I'm learning about authentication in Java and Spring and about difference between session and token based authentication.
I know that in session based authentication the user sends the username/password to server. It could send the credentials using a html form or basic authentication. After that the server create a session and send the session id in a cookie header like this set-cookie: sessionid, and when the user make another request it will use the session id in a cookie header like this cookie: sessionid. And the server compare the session id stored on the cookie against the session information stored in the memory to verify user’s identity and sends response with the corresponding state.
I'm not sure what's happen in the token based authentication. The user will send the username/password to server in the same way like in the first case: html form, basic authentication, etc. The server creates JWT and send the JWT to the user browser usually in the localstorage. But what I don't understand is how the server sends the JWT to client? Does it send the JWT in a Header like this set-authorization: jwt? What is the name of the header where the jwt is put? And after that when the client does a new request the JWT will be in an authorization header like this Authorization: Bearer jwt. So I don't understand how the JWT is sent from the server to the browser. Any feedback will be apreciated! Thank you!
What you said about Basic Authentication is somehow correct but not completely. In basic Authentication client almost always send the username and password to the server and server authenticate user by those information(it means client send those information in each request). something you said about coockie is not mandatory in basic authentication. client can store information like username and password in storage and send them on each request to server.
What about JWT and why is this much more reliable?
In JWT client use an authentication path to get the token from the server, so server provides client with an API like /user/authenticate and this path is usually secured by some other security mechanism(it can be Basic Authentication too) so client send username and password of the user to this path in header and it will get JWT token in Response Body, Then after for sending request to other resources(for instance /products) client send that token in the header of those request like this:
authorization: Bearer jwt
In JWT and other token based authentication mechanisms client should not save the username and password of the user somewhere in their storage. Something they could (or rather should) save in their storage is the token that they have received from the server, therefore something that is send in each request is the token and not username and password of the user as a result this mechanism is more secure.
Related
We are having an api gate way that requests user authentication using okta and then it redirects the request to a specific service, and sending it an authorization bearer token.
My question here is that how from this authorization bearer token we got in the service, we can get the user info using java spring boot?
Depending on scopes requested, your service can request user information from authZ server (Okta) presenting received access token (call to /userinfo endpoint).
Sometimes it can be configured on authZ server to inject additional claims into access/id tokens from a user profile, so that what I described above can be omitted
I feel unclear about authorization code flow. the main difference between implicit flow and authorization code flow is that authorization code flow validates the client(using id and secret). first i define the steps of authorization code flow and I raise my doubt from them.
Authorization code flow steps(some of them skipped)
Authorization code request send to authorization server then user redirect to login page
request contains
- response_type=auth code
- scope
- state
- redirect_uri
- client-id
if user credential are right then auth server redirect the url with auth code and state
client send post request to autherization server for access token
request contains
- grant type
- code (auth code)
- redirect_uri
- client_id
- client_secret
once auth server validated above request we get access token as reponse
using the access token client will access the resource server
My question is why we're sending client secret on 3rd step instead of first step. what if we send client id and client secret in first step and redirect user to login page so after he logged in client can get access token directly why auth code related steps needed.
How i expect above steps to be is
user click the link so request send to auth server. which validates client id and secret if they're valid then user will be redirected to login page
request contains
- response_type: access token
- scope
- state
- redirect_uri
- client-id
- client-secret
if user credential are right then auth server redirect the url with access token and state
using the access token client will access the resource server
client authentication can be done in first step why we need to drag it by sending client secret in 3rd step . why we need auth code related steps it's confusing can anyone explain the purpose of having auth code related steps?
Because anything the authorization server (maybe Google) sends to the browser is logged to the browser. "auth code" is very short-lived (not more than 1 hour). An access token is long-lived so if the authorization server sends the access token to the browser in the first step, it would be logged to the browser so if it is compromised through the log, someone else would access to the app on your behalf.
I am developing an app secured with Spring Oauth2, password flow.
But I'm still confused about difference between UserDetailService and ClientDetailsService flows in Spring.
As I understand from OAuth2 specification, client and user are different entities. Client has clientId, clientSecret and some grants, and User has username, password and also some grants.
Multiple users use the same client (mobile app or web browser in my case).
So I need to authenticate some user and provide it with an access token.
I have implemented both UserDetailsService and ClientDetailsService (with all needed infrastructure: AuthorizationServerConfigurerAdapter and ResourceServerConfigurerAdapter) and during authentication I see, that username from request is passed as clientId into clientDetailsService and
as username into userDetailsService.
But I thought it should be more complex process like for authentication request client should provide both client credentials and user credentials so then I can verify client (is it registered in my system) and its grants then verify user and its grants and then return an access token.
My questions:
Do I understand the process correctly?
Are client grants and user grants of the same meaning?
What classes should I customize to separate verification of client and user credentials?
Solution is stupid simple.
The client and the user are really different entities
To obtain access token you need to complete basic authentication with Base64 encoded client credentials in header and username/password of the user in params.
Header pseudocode:
Basic Base64("client_id:client_secret")
Params:
username=username, password=password, grant_type=password
This will return you access_token, refresh_token and some extra info.
I am using Spring Oauth 2 to secure a web application and to implement a three Legged security system and when it comes to using a
grant_type=password
I've noticed that the URL used to get a token for a user is:
Method : POST + Basic-Authentication header for the client
http://host:port/api/oauth/token?grant_type=password&username=xxxxx&password=xxxx
And my question:
Is this approach secure enough since it shares user's credentials on the URL ,if it is not what are the alternatives or improvements?
Is adding an SSL certification to the host would be a solution to that ?
Thanks
Plaintext authentication over an encrypted medium is not uncommon - so unencrypted passwords over an encrypted connection.
However, I would not send credentials in the URL. It looks bad and the same user might bookmark that URL.
You can put the credentials in the HTTP Header instead, and as long as you're sending them over an encrypted connection its ok.
The other option you have is:
Have the server create public and private keys for itself
Send the public key with the authentication/login pag
JavaScript encrypts the username and password with the public ke
Send over HTTP or HTTPS (still I would put this in the Headers rather than URL)
Server uses private key to decrypt and authenticate credentials
tl;dr
The easiest solution is, HTTPS and plaintext credentials in the HTTP Headers
How to call RESTful webservice (from Java - using RESTEasy/Apache HttpClient) which requires NTLM authentication within Active Directory, without necessity of entering user data again (domain, username, password) - user is already authenticated in Windows?
GET http://some_server/restapi/books
This works perfectly from web browsers or even java.net.URL library - user is not getting prompted for credentials, no 401 authentication errors - simply 200 OK is returned.
How to do the same using Apache HttpClient or RESTEasy client?
You can do that with this structure;
When user first enter username and password, you can check user
detail on active directory and if success, create an access_token by
using username and password. It may be sha-256 encryption(Refer here for creating sha-256)
Save that access_token to your db and give it an expire time.
After successful access_token creation, respond that access token to
user.
From now, you can use access_token for service requests
You need to save access token on client side like local storage. Same as if you are useing
http client, you can give that access_token in header.