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.
Related
Based on the diagram you can see above (Oauth authrization flow). Reference https://youtu.be/oKzeHshquCs?t=1949
Using user credentials (username, password), we are attempting to
get an authorization code (login).
Authorization code received.
Using the received authorization code we are now requesting an
access token.
When access token is given. This access token will be
now used to access the resource server (as Bearer Token).
I would like to ask how to implement this using API, using the latest implementation of OAuth2. Using custom REST API's on the Authorization Server.
Scenario: using two api's ('/auth/code' then ''auth/token'')
Using user credentials (username, password) the user will request on
api '/auth/code', where authorization_code as the response.
Using the recieved authorization code (from #1), we will request an access
token on '/auth/token'. Access token will be used as bearer token on
the authorization server.
Or if we can do this two step (#1 and #2 above) on one API process (auth/token) would also be great.
Do you have any working project in regards with this?
I have explored the code of Baeldung, but based on this implementation, it is still using the default implementation of spring security. It would be my great pleasure if there are Senpai's out there can help me with this. Thanks :)
There's no such API to get an authorization code directly passing the user credentials. Usually, there would be an API (/as/authorization), which redirects the user to the login page. Once the user enters his credentials, he will be redirected to the target application with the authorization code in code as the query parameter of the URL. (You need to configure your app's URL as a redirect URL or callback URL in the Identity provider)
This code is usually short-lived and can't be used more than a time. (i.e) You can use this code only once to get an access token. When you exchange the code with an access token, you should be seeing refresh_token (if you granted access to refresh_token grant_type in the IdP) as well with which you can request tokens in the future.
You need to configure all these things in an Identity Provider. This could be PingIdentity, Auth0, etc.
Make a call to /as/authorization API
Once user enters his credentials and redirected to the target application, extract the code from the query parameter and make a call to token API (oauth/token) to get access_token and refresh_token
Once the access_token is expired, use the refresh_token to get a new access_token (grant_type should be refresh_token).
Once the refresh_token is expired, you need to again get the authorization_code again with the /as/authorization API.
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.
As I understand, in authorization code flow we need to get authorization code and use it to get token after. We can get this code only when user confirms specified access. After that browser redirects us to redirect_uri and response will contain authorization code as parameter. So, the question: is it possible to get this authorization code without browser or any self made UI? Can we get it in application after correct request to, for example https://mysite.tuz/authorize ?
As you are using authorization code flow, the client requires a user agent (i.e browser or mobile app) to get the authorization code from the authorization server.
The whole purpose of using authorization code is that it can be passed via the user's web browser (user agent) instead of passing the access tokens directly via the web browser (user agent) which is not desired. Using authorization code,the Client then can directly retrieve an Access Token from the authorization server.
So the user agent is required to get the authorization code and act as an intermediary between client and authorization server.
If you do not require a browser then authorization code flow may not the correct choice. OAuth 2.0 supports several different grants i.e ways of retrieving an Access Token. Deciding which one is suited for your case depends mostly on your Client's type.
This might help you in deciding which flow to use
https://auth0.com/docs/api-auth/which-oauth-flow-to-use
You should use client credentials to obtain token without browser or any client. But if you need to use user credentials to get access token and id token of the user without browser or mobile app you need to implement you own client which will do the necessary logic for you and fetch the token for you. I already did it in java for the testing purpose. I don't know why you need to do it but you can implement your own client in almost any programming language . But in case you will decide to go this way you have to handle lot of things.
I expect your authorization server requires Proof-Key for Code
Exchange (PKCE) - so first of all before you start to communication
with server you have to create code verifier and code challenge
(google can help you with that :) in java it is quite simple)
Then you should start communication with server sending get request to url which ends with 'auth' you should send query params as: response_type (which is 'authorization_code' in your case), redirect_uri, client_id, code_verifier, code_challenge, scope, code_challenge_method (probably 'S256')
Then you receive I think two redirects from server so it is better to have some client in java which will automatically call those redirects. I used apache http client for my implementation. It has lot of features.
After successful redirect server will return login page to your client. It depends on authorization server but in this page you should put the data as username and password and submit the page. I have simply parsed the returned page and get the url for user authentication from it and simply make post request to that url with user credentials data sent in encoded form entity. In apache http client you will have all cookies from previous communication set (until you close the client) since apache http client automatically set all cookies returned in previous communication from server.
After make authentication request server will send you two redirects and you can store those redirects int http client context which you will provide for http client when you call authentication url.
In the last redirect there will be query parameter sent be server named "CODE" this is really important for you since you will use it to get token from the server
And finally you have to make one last post request to authorization server with url ended as token. So make a post request with GRANT_TYPE, REDIRECT_URI, CODE (you received in previous redirect), CLIENT_ID, CODE_VERIFIER (you have generated at the beginning);
Then authorization server will send you token and that's all
I'm trying to get oAuth working for accessing QuickBooks Online. I have a QuickBooks login/connect button embedded on a page that triggers the whole oAuth process. When it's clicked, a window pops up that is directed towards my apps getRequestToken endpoint. The handler (servlet) issues a request to the QuickBooks oAuth request token API, and it gets back:
Request Token
Request Token Secret
Authorization URL
So I have the response send a redirect to the Authorization URL. The pop up window now displays a QuickBooks login, after which there is a request to authorize my app with the users account. Once that's done, the pop up window is redirected to my apps getAccessToken endpoint (the callback URL that I included when calling the request token API).
From there, I obviously have to send a request to the QuickBooks oAuth access token API to get an access token and access secret, but apparently I need to supply:
Request Token
Request Token Secret
oauth_verifier
The oauth_verifier is provided as a parameter in the callback to my getAccessToken endpoint, as well as an oauth_token, but I don't understand how to get hold of the request token and request token secret from here. Am I supposed to have my getRequestToken endpoint store them somewhere once they're retrieved.
I'd prefer not to, but is this the only way to do it?
Am I supposed to have my getRequestToken endpoint store them somewhere once they're retrieved?
Yes. :-)
Does that answer the question? Yes, you need to temporarily store the request token somewhere while you wait for the user to arrive back on your site.
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.