secured spring boot backend with React Frontend - reactjs

i managed to secure my spring boot backend (localhost:8081) with keycloak as an authorization server (with an access token needed), but i want my frontend (react with port localhost:3000) to access the data which is secured. Thus meaning that localhost:3000/products should fetch data from localhost:8081/products after a successful login.
Could anyone guide me on this problem?

You choose an OIDC client lib for react. It should handle
redirection to authorization server for login
redirection back from authorization server with authorization code
exchange of authorization code for access, refresh and ID tokens
automatic access token refreshing
(maybe) automatically insert authorization header with bearer access token for configured routes
The requests your React app will issue to Spring resource server will then have required JWT access token.
PS
Make sure your Spring back-end is configured as resource-server (and not as client).
Also make sure that you do not use the deprecated Keycloak adapters for spring.

Related

Django Rest Framework Authentication - Session auth or Token auth

I have a project where I am creating a React frontend for users to sign SSL certificates. That frontend is used with a Django DRF backend to handle request. Currently, I have authentication specified in each of my views for token and session auth. I can authenticate a user through postman and through a python client using request. But I want to turn this around and be able to login from the front end using react and a login form and keep is secure and safe from XSRF. Ive also been reading about how token auth is insecure because of how tokens get stores in browser local storage.
So my questions are as follows;
Should I use token auth or session auth, and how do I decide which is best?
How to implement that authentication with a React login form?
And how I could protect this from XSRF?
Thanks in advance Stackoverflow Gods

Spring OAuth2 Single Page Application Integration to Azure

I have been tasked with integrating Azure Active Directory Authorization into one of our applications and have tried out some of the samples with relative success.
I have a Javascript SPA application (GoogleWebToolkit) that communicates with a Spring REST (not Boot) API. The Rest API is currently secured with Spring Security and login URL username/password etc.
I want to change this to use Azure OAuth2.
Being new to OAuth2 I'm trying to figure out if I should be using either of the following Spring options.
With this option all the configuration is done at the server side, client id,secret
If I do a href from the SPA front end to 'oauth2/authorization/AzureAD' URL, its sends a redirect to the Azure Login page, allows authentication and redirects back to what redirect URL I enter into the Azure AD console configuration. This works to a degree but trying to extract the token and pass it back is not working so far.
http.oauth2Login()
.clientRegistrationRepository(clientRegistrationRepository())
.authorizedClientService(authorizedClientService())
.authorizationEndpoint()
.authorizationRequestResolver(
new CustomAuthorizationRequestResolver(
clientRegistrationRepository(),
#Bean
public ClientRegistration clientRegistration() {
ClientRegistration.Builder builder = ClientRegistration.withRegistrationId("AzureAD");
builder.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST);
builder.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE);
........................
or
I haven't fully tried this option yet, but I think it involves doing the authorization directly from the SPA javascript front end, put all the values for the client id/secret into the javascript FE etc, and then passing the once acquired token via the Auth header for validation by the server side. Like at https://www.baeldung.com/spring-security-oauth-jwt
.oauth2ResourceServer()
.jwt()
.jwkSetUri("https://login.microsoftonline.com/common/discovery/v2.0/keys");
Could someone confirm where I should be using Option 1 or 2, and if I am understanding things properly?
Your understanding is correct in option 2. As per above scenario, let’s consider Front End Application which is Single Page Application (Java Script) to be OAuth Client App to orchestrate the process of obtaining access token and then grant access to resources from Spring back-end application.
So, here client Application need to be registered in Azure AD to acquire the access token secured by Azure AD.
We recommended MSAL libraries which helps to acquire tokens from the Microsoft identity platform and handle token in many ways to authenticate users and access secured web APIs.
Both the applications (front end and back end) need to register in Azure AD based on the scenario.
Update client-id, tenant-id, redirect URI to front end application configuration file based on application registration in Azure AD.
Back-end application also need to be registered in Azure Ad to secure by Microsoft Identity which can then define the delegated permissions(scopes) your API exposes.
Then business logic needs to add in back-end application to determine what is allowed or prohibited based on these scopes in access token.
To authorize the client request in Spring application:
Users will start by authenticating with a username and password in front end application.
Once authenticated, the client will receive a JWT representing an access token.
The client will include the access token in the authorization header of every request to a secure endpoint.
The resource server will validate the access token and determine if it has the right permissions, using the information within the token.
In this case, Spring serves as resource server and not acquiring any token in the back-end application .
Security Configuration in Spring provides numerous methods to add filters to the HTTP request to authenticate each request.
Here,
http.cors() will allows Cross-Origin Resource Sharing (CORS) checks to succeed.
All the requests need to authenticate before passing to the application(controllers).
Spring application serve as a resource server and authentication should be provided via JWT access tokens and further validate the roles and scopes in the application’s controller using #AllowedRoles annotation.
Our JWT access tokens are signed by Azure AD and application should check if their signature is correct. Azure AD has an endpoint with the public key to do so, which need to configure in spring application.
Also, as mentioned, we will need access token to call the protected back-end application because contents of the token are intended for the resource (back-end API) to perform authentication and authorization.
To validate the token, you can search the keys endpoint in the discovery document and then provide this JSON web key (JWK) endpoint straight away where JWK URI can be found.
# application.properties
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://login.windows.net/common/discovery/keys
Note: The flow would be same to get the access token while integrating with Azure AD. i.e in Spring boot or in spring.

How to SECURELY connect my next.js frontend with next-auth to my springboot backend

I am building a frontend with next.js right now, which authenticates with GitHub OAuth using next-auth.
Next-auth handles all the authentication including the session and saves all that into a database, in my case a Postgres DB.
I now also want to connect my frontend to a spring boot backend server via REST API, which handles some file access. I could simply include the session token into the authorization header and connect my backend to the Postgres DB also and check if a session with this token exists.
But this approach seems not right. What is the best way to secure my backend here? How can my backend check if the user is logged in with GitHub?

React SSO using SAML without web server

I have a web app developed using Create-react-app
I host it on IIS, the IIS only response to load the app, there is no server side logic on it (no Express or any other web server)
The app is using a RESTful API on the same IIS, it is out of my control (I cannot make change).
Now one of my client request to add SAML SSO to our app.
I would like to know:
in normal situation, which one is the Service Provider? My IIS Web server? or the API service?
For my case, I cannot implement SAML to API service, my web service only used to load my app without server side logic, how can I implement SAML?
Could any one give me some React implement SAML SSO tutorial or article for reference?
Thanks for any help, any information or suggestion are welcome!
in normal situation, which one is the Service Provider? My IIS Web server? or the API service?
I assume the client wants to authenticate the users using their internal IdP. So your application is the SP. But you will have to define different token service (details below).
With SPA (a single-page-applications) I see the problem, in SAML the user is redirected or posted away from the SAML request and SAML response.
I have a login page to enter id/pw, post them to API server Login endpoint to authenticate and get back a JWT token. After that we use that token in API calls for authentication
The API services are using a JWT token issued based on the provided username/password. I'd recommend to extend the token service (or use a different service) to issue a JWT token based on the provided SAML response - a token swap service. In many OAuth implementations it's called SAML grant type.
I cannot implement SAML to API service, my web service only used to load my app without server side logic, how can I implement SAML?
Usually after the authentication the user is redirected or posted to the SAML ACS endpoint URL, where the server can create sort of session (cookie, parameters, token, ..) and the user is redirected to a URL returned the web page with the session information.
If you are using an SPA, you could use a popup window or SAML with redirect (not with post), where the page could read the SAML response parameters (assertion, signature, ..) and use them in the token swap service mentioned above.
When processing the SAML response, try to use some mature, known, out-of-box libraries, it's a security service and not doing it properly may cause security weaknesses. But you need to do that on the server side, as at the end you need the JWT token consumed by the APIs.

Implement CSRF in ReactJS PWA with ExpressJS proxy to API backend

I have the following setup:
ReactJS PWA frontend application that uses service workers to cache the source code to the client.
ExpressJS Reverse Proxy which relays any request that would go to a backed API. This handles a login process and stores a token on the server and sends a session cookie to the client. The cookie is HtttpOnly, SameSite, Secure and signed. The proxy also checks if the connection is secure, referrer is in white list and exact match and same for the host.
Backend API is on a different server with OAuth login protection.
Express returns a server side rendered page on the first load then ReactJS hydrates that page and uses as an SPA. Every file afterwards is cached into the browser.
Every request that comes from the client app is handled with the same token as they are not user specific operations. User specific operations require e-mail and password to get a new unique token from the API.
My issue is:
An attacker could create a cookie and send it along with a curl request to the proxy. This would by pass my ReactJS app as both referrer and host can be faked.
I would like to find out how can is secure the connection between the ExpressJS proxy and the ReactJS PWA.
I was thinking about CSRF with csurf but that would not work. If the PWA is installed on a phone's as an app, then it would only access the Proxy when the request is sending. Therefore I cannot set the CSRF header.
If I was to add the CSRF token to the very first request when the client hits the server and the page is rendered with SSR, I would only set the token only once, which can be re used as many times as the attacker wants.
Is there a proper way to lock the proxy to the app somehow?
I cannot store anything in Local storage and I cannot hard code tokens into the source code of the app. (They are insecure options)
Thanks!

Resources