this is my sample application. GATEWAY is the entry point for all other applications. Basically it's the proxy. It's capable of csrf protection. When I access the url localhost:8080/login firstly csrf token is created for GATEWAY and then request is forwarded to backend service (UAA).
Problem is that UAA generates it's own token (_csrf) and one generated by GATEWAY in header as X-CSRF-TOKEN is completely different.
So how can I avoid this conflict? Is there any simple solution to share tokens between applications?
Thanks
Related
I'm writing a micro-service with quarkus and eclipse micro-profile. Part of it is reading some configuration from an REST endpoint with a simple GET. So far so easy.
The webservice endpoint needs JWT authentication. To get the token I've to call another endpoint with basic HTTP authentication. The server does not use a standard like OAuth or OpenID. I only find micro-profile examples without or only basic authentication.
So my question is, how can I implement that process with micro-profile? I need to authenticate first, put that JWT header into the RestRequest and be aware of the expiration. Maybe there is some help in the framework?
Thank you
If your auth provider uses a custom auth scheme, then you will have to write your own ClientRequestFilter that handles the process of obtaining the JWT and then passing it to the original request as auth header.
You can have a look at existing Quarkus OIDC client filter here
basically you need to implement the getAccessToken method, where you would make a request to your Auth endpoint, exchange hard credentials for a token, and then use the obtained token. To improve performance, you should store the tokens in a cache/AtomicReference with clientctx as key, so you can reuse them if they are not expired on subsequente requests.
I'm trying to call a 3rd party endpoint that requires authorization using Java spring rest Api, so I need to execute an Authorization Code Grant Flow.
I understand the flow where I need to first get the code then exchange the code for a JWT and finally use the JWT to be able to do the secure call.
What's not making sense to me is how am I suppose to set up a redirect URI when I'm using solely working with a backend rest api with no UI. Usually the user is redirected to a login page where they either login with a username/password or 3rd party accounts (google/facebook...)
After alot of googling, all the searches ended with guides to secure my own endpoints rather than access a secure endpoint from my spring boot service
Edit: It's worth mentioning that I'm using solely a backend with no front end (or MVC) whatsoever, after #Partha's comment I did the following:
First, I added a new login endpoint, when accessed via browser(this won't work with swagger/postman) it should redirect the user to the Authorization Server:
#GetMapping
public void login(HttpServletResponse httpServletResponse) {
httpServletResponse.setHeader("Location", getAuthServerEndpoint());
httpServletResponse.setStatus(302);
}
Where I built the endpoint to have all the data needed (client_id,redirect_uri...) so it looks something like
https://idpserver.bla/oauth/authorize?client_id=xyz&redirect_uri=http://localhost:8080/token&response_type=code&scope=xyz
Now it sends me to the Login page of the auth Server, after I login, I expect it to redirect me to localhost/token (which is a get request that would retrieve the code and do a post request to get a jwt and save it) but instead, I'm receiving a invalid redirect uri and I'm really not sure if this is an issue from my implementation or the server's
EDIT2: I did a dumb mistake by NOT adding http://localhost:8080/token as a redirect url in the Auth Server since I assumed I didn't need to
Not really sure how are you trying.. idea here is .. your api server should have a get endpoint /login. In your controller of /login , you should redirect to IDP say http://idpserver.bla?client_id=xxx&grant_type=code&nonce=yyy&redirect_uri=http://localhost:8080/token ( note, its redirect, not make an api request ). So, with this, when you hit http://localhost:8080/login in ur browser, you should see it being redirected to IDP. now you enter ur credentials, IDP validates that and redirect back to http://localhost:8080/token?code=XYZABC or something similar. Your controller code of /token API should read the code from url param. and make a call (this is api call, not redirect) to IDP to exchange the code for a token ( idToken / accessToken) based on your scope. And using the token you should be able to access protected resources. Hope that helps
Depending if you are using MVC or Webflux a different approach will be required:
MVC: include a "security filter" to do that. You will be able to see an example in the following links:
MVC Securiry Manager
MVC Security Filter
MVC Security Configuration
Webflux: configure your own security manager. You will be able to see an example in the following links:
Webflux Securiry Manager
Webflux Securiry Context
Webflux Security Configuration
As you can see in both ones, an external service is called (using RestTemplate in MVC and WebClient in Webflux), to get the required authorization information and decide if the "logged user" pass the required security logic.
You can adapt it in the way you need.
I'm going crazy trying to figure out how to implement a CSRF protection for my Web app. I've read tons of pages but still cannot decide on the solution in my particular context.
So, first my Web app is written in Angular, deployed statically on an Apache server. It calls some services on my server, Java type, deployed in a war on an application server. Both of them are deployed on the same domain. After authentication the usual session cookie (secure+HttpOnly) is set in the response.
Now, I would like to implement a CSRF protection based on either a synchronizer token or a double submit cookie pattern (but from what I saw the first is a better solution as I can handle a state on server side).
Most of the solutions I saw are proposing to generate the token server side and to store it in a cookie so it can be accessed on client side. The constraint for this to work, and I would that it is a big one, is that the cookie cannot be HttpOnly, as Javascript would not be able to access it. Moreover I have the feeling that sharing the token in a non fully protected cookie wouldn't be a good idea. But it seems to be the recommended solution from AngularJS ...
So, if I discard this solution what am I left with?
Putting the token not in a cookie but rather in the response header? Is it secure?
Exposing a service to fetch the token? Seems practical but not sure if it is a good idea?
Expose a servlet to build a Javascript to provide the token, like in OWASP Guard?
Anything else?
EDIT: It seems that Spring is going for the injection of the token name and value in the HTTP response as a solution.
Thanks for your help!
CSRF token should generated once per user session.
It should be stored in server side session (HttpSession in case of Java)
Client should store the token as a hidden parameter not in the browser's cookie.
Server should validate the presence of the CSRF token for each request and compare with the token stored in session.
More details : https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet
We have a Java 8 backend application using SprintBoot with an embedded Jetty server.
The UI for the application is a Single Page Application built using React.
Currently I have enabled authentication by integrating with Okta using the spring security SAML extension. When the assertion is posted by Okta to my app, I create a session and the JSESSIONID is sent in the cookie.
This was fine until now when we had a very simple UI serving few UI components.
However, now we have several REST endpoints in our backend and we would want them to be authenticated as well. REST endpoints themselves are developed using Jersey.
If I understand correctly, SAML is clearly not the choice for pure REST based endpoints as SAML is mainly a browser based protocol. These REST endpoints will be called by our UI as well we want them to be independently called via Postman or something for testing.
When a client would call these REST APIs, I am guessing the client should send an Authorization header which should be checked by one of the authentication filters in the backend. After validating the client and the user, the filter should inject the user information in the SecurityContext because Jersey injects SecurityContext in all of the REST endpoints. Then it becomes easier to fetch the user from this SecurityContext.
Upon reading, it seems Okta OpenID Connect can be one choice which issues a JWT. However I am not clear on how to use this. That is, when Okta issues a JWT should our UI or any client for that matter keep sending the JWT in the Authorization header to our APIs and then our APIs in turn should send the JWT to Okta to validate it?
Question is what is the best choice to serve both, a login for the UI and a session and authenticating REST endpoints? Not to mention the REST APIs will be stateless in nature.
When a client would call these REST APIs, I am guessing the client
should send an Authorization header which should be checked by one of
the authentication filters in the backend
In OpendID Connect (OIDC), that value in the Authorization header is id_token which can be in JWT format. This id_token is issued by the OIDC server as the last step for whichever OIDC grant type you choose and applicable to your case.
Upon reading, it seems Okta OpenID Connect can be one choice which
issues a JWT. However I am not clear on how to use this. That is, when
Okta issues a JWT should our UI or any client for that matter keep
sending the JWT in the Authorization header to our APIs and then our
APIs in turn should send the JWT to Okta to validate it?
Think that you have 3 components in this architecture. Relying Party (client), Identity Server / Authorization Server / OIDC Provider and Resource Server (your backend and it's data). When Authorization Server issues and id_token to Relying Party, your Resource Server also knows this token. So when you request for data in resource server, you will present your id_token to Resource Server and it knows if it is valid id_token or not
Question is what is the best choice to serve both, a login for the UI
and a session and authenticating REST endpoints?
OIDC Provider (or Identity Server if you need more complex operation), since OIDC is Authorization (OAuth 2.0 at core) and Authentication.
I have OAuth2 implemented in my app with Spring Security. Currently, it works with the "access_token" request parameter. Where can I add some customization to also accept the token from a cookie?
You cannot get the token from a Cookie - using oAuth, the only way to get it is via a call to the oAuth server, getting a code, and then getting the token...
You can read the oAuth spec.
If you talk about the application-end (and not the oAuth), it might be possible.
Checking the token is the responsibility of the application that holds the protexcted resource. There, rather than getting the token from the header of the request, it can check a Cookie instead.