I`m new to OAuth 2.0 and am trying to develop a application using a third party OAuth provider with Authorization Code grant flow as ny Authorization Server and Spring Security.
This provider gives me two endpoints /authorize and /token and those two, after the user authorizes its access, will return a access token.
So far, I have secured the "/" endpoint, so the application redirect the user to the authorization page and then, in the callback endpoint, store the token so it can be validated by a filter in each request.
But, as the application is mainly a set of REST API's, we want to be able to test it using Postman, with that said, on Postman, I am getting the token by setting the Authorization as OAuth 2.0 and requesting the token directly from the third party endpoints but, as Postman have its own callback URI, my application doesn`t store the token generated.
So, my two questions on this are:
Using /callback endpoint to store the token and validating it before each request by a filter is the common way of doing it?
To use Postman, should I create an endpoint for storing the token generated outside the application context or should I create an Authorization Server of my own as an additional layer on top of this third party AS?
Since your application is a set of REST API's, you need to make it as a Resource Server (in terms of OAuth2).
Resource Server doesn't perform authentication itself, it only validates a token from Authorization header (Resource Server in a nutshell).
You can find an example in Spring Security samples: oauth2resourceserver
I eventually come to the conclusion that I was using Postman wrong the whole time.
So, by the end, we got the Token saved on the database when the user logs in and, then, return it to the caller, whether it is the Front-end application, or Postman itself.
Then, in every call to the API's, the caller should include the token as Authorization on the header and a Filter on Spring will check the token against the Database.
Related
I am working on the ASP.NET MVC 5 web application. It has only one layer which contains views as well as business logic/operations. Business logic is logically separated from UI but it is not behind a separate web service/API layer.
Now when I use OIDC and OAuth2.0 for my application, there is no separate Resource Server, so to say. Because Client itself has all the Resources I want to have access to.
I am using Authorization Code Flow for authentication & authorization.
Questions:
Does access token have any role in this case? If yes, what?
How am I going to practically use the access token? Since the client itself is the resource server, there is nothing to which I need to send access token to.
I guess you get an ID token which contains all the information you need for authentication of a user. If not, you can use the access token to get the user info. If this is all the information you need, then the access token is not needed anymore. This happens, because OAuth2 is a permission delegation protocol, not an authentication protocol in a first place.
When you have the user info, you can implement between the browser and your ASP.NET backend in any way. You can take a look at the OAuth 2.0 for Browser-Based Apps RFC.
In this case you should use Client Credential flow instead of Authorization Code flow.
In Client Credential flow, your application would send your client id & client secret to Authorization Endpoint directly and asking for access token. Authorization Code is not needed in Client Credential flow. Details as below
An authorization code flow typically need your client redirect
resource owner to authorization endpoint and get a authorization
code from authorization endpoint, client than uses this code to get
access token, at the end of the day client uses access token to
access protected resource.
In Client Crendential flow. your client app is actually the owner of
your resource. So no need to asking for a authorization code. direct
uses its own client credential to get access token from
authorization endpoint and use that access token to access protected
resource(Resource server)
If I authenticate with OpenID connect, I can authenticate my SPA ok.
How do I use the obtained access token now to access my own REST resources?
It's a simple question, but I don't find satisfactory answers.
A prominent answer I always find is 'use oidc when you don't have a backend'.
Now that makes me wonder if ever a webapp was created that didn't need a backend.
Oidc is almost always the answer when the question of storing a refresh token in the client pops up (like in 'use oidc, it's a better architecture and ditch the refresh token') but it doesn't really explain anything.
So when the user logs in with, say Google, he obtains an identity and an access token (to ensure that the user is who he claims he is).
So how do you use this to authenticate at your own REST service?
The only real way I see it as stateless is by sending another request at the server to the provider on every request to the REST api, to match the identity to the validity of the access token there.
If not, we fall back to the good 'ol session vs jwt discussion, which doesn't quite seem to click with the oidc because now we're duplicating authentication logic.
And the good 'ol refresh token in the browser is generally promoted as a bad idea, although you can keep access tokens in the browser session storage (according to the js oidc client library), autorefresh them with the provider and that's fine then (-.-).
I'm running again circles.
Anybody can lay this out for me and please break the loop?
Your SPA (frontend) needs to add an authorization header with access token to each API request. Frontend should implement the authorization code flow + PKCE (implicit flow is not recommended anymore) + it needs to refresh access token.
Your API (backend) needs to implement OIDC (or you can use "oidc auth" proxy in front of backend) - it just validates access token, eventually returns 401 (Unauthorized) for request with invalid/expired/... token. This token validation is stateless, because it needs only public key(s) to verify token signature + current timestamp. Public keys are usually downloaded when backends is starting from OIDC discovery URL, so they doesn't need to be redownloaded during every backend request.
BTW: refresh token in the browser is bad idea, because refresh token is equivalent of your own credentials
I am building an Angular SPA app and using Okta as an Idp. since its an SPA so I think I need to use Implicit flow. I have two queries here-
Since in Implicit flow a refresh token is not issued, does it means that th user will be logged out of the app after the token expires and he has to log in again?
Why do I need to use Implicit flow in case of SPA? why not Authorization code flow? since I have control over both the front end (SPA) and back end (REST API) . for example in case of Spring MVC architecture for the web app Authorization code flow is possible.
Thanks,
pchh
Yes, if the token expired, you have to re-autenticate. Normally you still have a valid session on the identity providers site, so you can do a "silent" login using an iframe. Libraries like oidc-client support a silent login, which can do this for you.
You need to use implicit (or hybrid) flow, when you need to access to the access token from your javascript app. With authorization code flow your javascript app doesn't get the access token, so if your API needs an access token for authorization, what are you going to send?
If your auth server supports OpenID Connect (OAuth2 extension) and single sign-on (SSO) feature, to get a new token before the old gets expired, use an iframe with a URL you used for authentication, but add prompt=none parameter (and possibly id_token_hint parameter). See OpenId Connect RFC. The prompt=none parameter tells the /auth endpoint to issue a new token(s) if the user has an open SSO session at your OAuth2 server. If not, the request will fail. There is a separate RFC for session management.
The Authorization code flow requires you to access the /token endpoint, which usually requires authentication (client ID + client secret) and you cannot keep the secret safe in a browser. For this reason, the token endpoint doesn't use to support CORS headers, so you cannot access it using XHR. Using the Auth code flow, you get a code as a redirect URL param (?code=), which gets to the server hosting your SPA (browser sends it there after redirect). The implicit flow returns tokens in hash part of the redirect URL (#access_token=), which stays in a browser (it's not sent to the server), so it's safer.
In OAuth 2.0 flows the authorization server sends the authorization code to the redirect endpoint and then the webpage has to hit the server again to get a separate access token to query the protected API with.
Why do there have to be two tokens? Specifically could someone provide example(s) of security attacks/vulnerabilities that emerge without this design.
There is this post Facebook OAuth 2.0 "code" and "token" but it doesn't really fully explain the reasoning behind the design.
One (the authorization code) is exchanged in the frontchannel, the other (the access token) in the backchannel. The end goal is obtaining the access token. Since the frontchannel is inherently more insecure it makes sense to send a very short-lived one-time-usage-only temporary credential (i.e the authorization code) in the front channel that the web server can use to obtain the longer-lived repeatedly-usable access token in the backchannel. That backchannel call would also allow for the web server (or: Client) to authenticate itself to the Authorization Server to increase the assurance about dealing with the right party.
Generally OAuth definition says that it is way where user gives an application access to his resources stored in other application (without exposing the actual username and password). But inside Owin, it is a way to implement token based authentication within an application. Although we can deploy the Authorisation application at different server. But crux remains the same. Could anybody shed some light. I am very confused.
Thanks in advance
If you take a look at the OAuth 2.0 spec you will find this:
The authorization process utilizes two authorization server
endpoints (HTTP resources):
o Authorization endpoint - used by the client to obtain
authorization from the resource owner via user-agent redirection.
o Token endpoint - used by the client to exchange an authorization
grant for an access token, typically with client authentication.
As well as one client endpoint:
o Redirection endpoint - used by the authorization server to
return
responses containing authorization credentials to the client via
the resource owner user-agent.
Not every authorization grant type utilizes both endpoints.
Extension grant types MAY define additional endpoints as needed.
So basically, you have 2 options:
1) Use the authorization endpoint where your end-user is redirected to a form that is handled by the authorization server
OR
2) Create your own form inside your app, get the end-user credentials and send that data to the authorization server, where it will be validated and return a token for you to use.