How can delegate Access Token acquisition to a BFF? - spring

There is a several options on how to secure access to resource APIs from clients(web/mobile...), And in recent years, it was common to implement OIDC for SPAs in JS / TS, and this is no longer recommended.
The recommendation for SPA is to avoid storing tokens in the browser Or using service worker, And use a BFF insted of direct connect to Identity Server.
In this approach the BFF works as proxy of Identity Server and handle all oauth requests.
What is the best practice to implement this pattern with spring BFF, Or if there is another better approach.

Perhaps you're aware of this doc which explains the options. Assuming you are using an SPA and don't want the website option, there are 2 options, identical from a security viewpoint, and which you use is a matter of preference.
WEB BACKEND
The SPA sends OAuth and API requests to a web backend first, which forwards them and implements the OAuth client. The web backend uses a runtime that issues cookies.
Pros are an easier initial developer setup and fewer components to deploy. Cons are that all developers have to run the backend, and web deployment options are limited to those that can host the runtime.
REVERSE PROXY BACKEND
The SPA sends OAuth and API requests via a reverse proxy such as NGINX. OAuth requests are forwarded to a utility API. The web backend remains static content only.
Pros are that you can get rid of the cookie issuing runtime from a developer PC, and it is easier to do things like deploy web resources to a content delivery network. Cons are that the initial developer setup is harder and that there are more moving parts.
BEHAVIOR
In both cases the SPA uses URLs like this, for static content, oauth client and API routing responsibilities.
https://www.example.com
https://www.example.com/oauth-client
https://www.example.com/api
Within the oauth-client path, the SPA calls endpoints like this. The SPA OAuth code is very light:
POST /login/start
POST /login/end
IMPLEMENTATIONS
There are quite a few out there, including components you can plug in. Search for a term like BFF OAuth and do some reading. It is a journey though - cookies are complicated little things.

I have just added a tutorial on one of my repos for configuring spring-cloud-gateway as BFF between a browser application secured with sessions (Secure HttpOnly cookie) and an OAuth2 resource-server.
This sample uses Angular as UI framework, a thin wrapper of mine around spring-boot-starter-oauth2-resource-server, and Keycloak as authorization-server, but this are implementations details are all the work is done by the BFF.

Related

spring boot security use keycloak sessions

I'm new to security and I'm trying to understand how to implement proper security without any overkill.
Below are my questions.
I don't want to allow 3rd party clients to use my API and hence I don't see any importance of OAuth 2.0. Hence I'm looking to use the sessions generated by keycloak (or Ory Kratos) in my Spring Boot Security. Any guidance on how to do that.
I have come across an application https://opstra.definedge.com/ which security is implemented using keycloak (can see the URL pattern). But in the requests, I can't see any JWT token in the chrome DevTools Network Tab while performing any network requests. I think they are implementing it the way I wanted. Any overview on how it is implemented.
I'm not architect at definedge, but I'm pretty sure they do not use Keycloak sessions in Opstra (they would have to run Opstra inside Keycloak servlet for that). It more looks like they use OAuth2 to authenticate users from a Java client and that this client has sessions of its own enabled (JSESSIONID cookie for opstra.definedge.com VS sso.definedge.com). It is quite possible that this java client uses access-tokens to authorize requests to resource-server(s), we just can't see it from the browser.
Restricting the clients allowed to consume your API has little to do with authorization method:
with basic authorization header, any client with login and password can access
with Bearer authorization header, any client with a valid token can access (which you already had anticipated)
even JSESSIONID cookie can be set for any origin (I believe), in which condition any request from the same browser would be authorized, whatever the web client.
Restricting your API clients is more about CORS configuration, which aims at just that: filtering which origins (host + port) can access which resource location (URL)
There is a notion of confidential client in Keycloak where the client must provide a password in addition to client-id to exchange authorization codes for access-tokens, but this does not apply to rich clients (clients running on devices you cannot trust): Angular, Vue, React, native mobile apps, etc. code can be reversed enginereed to read that password. But it is possible to configure a Java client of your own as "confidential" and as so, allow this client only to get access tokens to query resource-server (API).
OAuth2 comes with much more than just easing multi-client scenarios and JWTs with session-less java applications greatly ease horizontal scalability and fault tolerance. You should read this article for a refresher on
OAuth2 (and its value)
resource-server security configuration (with CORS)

Secure SPA - OAuth Confidential Client (BFF pattern)

i want to reach a confidential client for my backend-system.
The SPA is an angular app. The backend a spring-boot application with different rest-endpoints which stores the objects in a postgres-db.
Actual my SPA got a login page which are connected to the oauth-server. My SPA is currently a public client (client-credentials are stored there). I want to reach a confidential client.
I attached a picture above. The SPA triggers the login. The backend now takes over the authentication, so that the backend is now the client. The backend receives the access token and stores it in a session db. The backend then issues an httponly cookie to the SPA so that the session is secured accordingly.
Is my architecture possible? Are there any examples somewhere? I have no experience in session management and want to programming as less as possible to avoid mistakes and vulnerabilities.
Thanks for help!
yes, you can setup a reverse proxy in the backend that will perform the OAuth 2.0 BFF task, for example see:
https://hanszandbelt.wordpress.com/2017/02/24/openid-connect-for-single-page-applications/
https://github.com/zmartzone/mod_auth_openidc/wiki/Single-Page-Applications
https://curity.io/blog/token-handler-the-single-page-applications-new-bff/

Autorization Code Flow with REST API "backend" on a different domain

We are using OIDC and IdentityServer in an enterprise deployment where at the moment we control everything (OP, clients, resources, users).
We have an SPA client that connects to its "own" API and will go through it for everything it requires to do. They are however being served from two different domains. (Let's say the application runs on "my.apps/app" and the API in "my.apis/api").
In our current setup, we use Implicit Flow to have the user authenticated in the SPA and then call the API and verify the token within it. This works very well.
We treat our API as a "resource" even though we don't need to and we don't require the user to give consent.
As mentioned, the SPA needs to go through the API for everything it does and this also includes augmenting user properties upon authentication, so the client doesn't even really let users work with it without going through the API.
Given that scenario, our thinking was that we could even be using Authorization Code flow for our OIDC authentication (treating the API as a backend) and get the security "benefit" of the browser never having access to the tokens.
However, due tue the applications being hosted separately we think this would require us to either:
Initiate the authentication request in the SPA, get the Authorization Code in the fragment but pass it later to the API which will in turn request the tokens and have them live in a cookie or something along those lines.
Initiate the authentication request in the SPA but use redirect_uri to the API domain, thus giving the Authorization Code to it which will request the tokens, have them live in a cookie and then redirect to the SPA again.
Basically we want to know if this is a setup that you think would work, what are the security concerns if any, and if it would be recommended for us to go ahead with this or to keep using Implicit Flow instead (specially from a security standpoint).

Malicious requests detecting/validating requests

Application has front-end and back-end modules, front-end calls rest services from the backend written on Java/Spring.
Is there any best practices how to detect malicious request generated not by the front-end (if some user try to call service direcly from the back-end via rest client)?
Maybe generating some hash value for every request on front-end and decrypt this value on back-end validating this request?
What you need is authentication. The backend needs to authenticate either the frontend web app, or the user itself.
Probably the most common way is authenticating the frontend, which practically means that frontend and backend have a shared secret, authentication takes place upon each call, and the backend trusts the frontend. This can be achieved in countless ways from http basic auth (over https of course) to some kind of an api key mechanism (signing requests, etc.) You don't have to reinvent the wheel, depending on your usecase and threat model, http basic auth over https may very well be enough.
Another way to do things is to delegate user credentials to backend services. This is most often achieved by passing single sign-on tokens from the user to the backend, effectively impersonating the user when the frontend calls backend services. Arguably this is more secure, as for instance it does not need that level of trust between web and app, but services still need to trust the SSO component that issued the token. The point is that there is no secret for an adversary to steal (let alone from the frontend server, which may be an easier target), so it may be more difficult for an attacker to issue requests to backend services, even if some backend and/or frontend servers are already compromised.
So while I think an answer here is not the right format to go into details about how exactly to do this authentication (there really are multiple good solutions, and in every case, implementation details matter very much), at least conceptually these are your options I think.

Recommended way to secure ASP.NET 5 Web API application

In previous versions of ASP.NET you got authorization and authentication out of the box from the default template.
I have a Web API application and three or four well defined clients that will consume it and I need to secure it.
I read about OpenID and OAuth but they seem like an overkill for my problem.
What's the simplest way to achieve that?
These would be the 3 best solutions if you require security:
WEB API browser client: Implicit OAuth 2 flow
WEB API Application client: OAuth2 code flow
(With OpenId)
OR: Cookie Authentication with Cross-site request forgery protection. (Default template MVC 6 website template)
If your application is public, I would use at least one of these, otherwise it depends on how secure your data must be.
Well, it depends on your scenario. If you don't need authentication (because it's a server-to-server scenario), use a security token as described below. If you need authentication of the user, you may use Basic or Digest security combined with HTTPS.
In a security token scenario, the client simply has to add the token to the request headers and the server needs to validate the token. Make sure the requests transit as HTTPS to make sure the token is encrypted. Remember, this method is only valid if you know the applications that will access your API will be in a secure environment (another server, for example). Otherwise, I would go for another solution.

Resources