Spring Boot REST service – End User Authentication vs APP (REST client) Authentication - spring-boot

I have gone through many posts and articles but didn't find a straightforward solution for the case below which I have to implement.
Platform: Spring Boot 2.x.x (Spring Security 5.x.x) with embed Tomcat
Solution: REST service that consume many client apps and many end users.
I have to implement a REST end point /api/search which accessible for many client application. As an example, web application APP-X (Angular), web application APP-Y(Jquery/Bootstrap) and mobile application APP-Z (IOS). All three clients are separate entities (both technical perspective and business perspective).
So I have to authenticate above application using onetime token. Therefore I planned to go for Spring OAuth2 by enabling #EnableAuthorizationServer and #EnableResourceServer. For each app client I’ll generate a token and they can use it when they connect with my REST service. Is this approach correct?
Apart from the app clients system has capability to register and login functionality for end users. Also my end point (/api/search) can access both anonymous users and users who registered under ROLE_REGUSER role. And through the security context, I need to access the user details as usual user authentication.
This is the place I got stuck. How can I handle the following points together using Spring Security 5.x.x (Spring Boot 2.x.x).
I. Both client apps and end users authentications.
II. Allow access for anonymous users and registered users for same end point.
I have attached small diagram to elaborate the above scenario.
Thanks

I found a solution when I upgraded my spring security version to 5.2. In version 5.2, they have depreciated #EnableAuthorizationServer and #EnableResourceServer. So I had to move with an external authorization provider who supports auth2. I chose AWS Cognito, and fulfill the above requirement, using the user pool option.
In AWS Cognito
I created a user pool.
Then created two app clients in the same user pool.
One app client configured as support to the client credentials flow.
The second app client configured as support to the user authentication flow.
In client applications
Retrieve access token directly from AWS Cognito using client credentials and used to secure all API calls.
If a user login at any stage, retrieve access token directly from AWS Cognito using the authorization code and replace any existing access token.
The advantage is, the resources server can validate any access token that generated related to the same user pool.
In resources server (backend API/Spring Boot)
Validate access token.

Related

Spring webapp with multiple auth type: basic and social login togheter

I wrote a spring boot webapp with spring security authentication over jpa. It uses jwt to grant access to a simple html/js application.
I'd like to add oauth2 flow in order to allow users to authenticate over github or google or whatever cloud system.
What kind of solution may I adopt to target it?
I see many applications like udemy, for example, or others. They allow multiple authentication types:
username and password
google account
facebook account
How may I replicate this behaviour in my webapp?

custom oidc in keycloak

I have a spring based application which does authentication and authorization(oauth2 based) for a client app.I want to now use keycloak to manage my authorizations, but i want to keep my spring code. Basically i want to use my existing auth code as an external identity provider in keycloak.
I am thinking of adding changes in client app such that it receives token from my existing oauth code(which does the authentication) and then exchange this token with keycloak(for session and authorization management). How can i do this? What configurations need to be done in keycloak?
I read about token exchange in keycloak here, but i am not clear about the kind of token i need to send from my existing auth code.
https://www.keycloak.org/docs/latest/securing_apps/
Here is how OAuth2 roles are usually spread:
Keycloak is authorization-server
Spring service is resource-server
front-end is client
user is resource-owner
I have a doubt of you wanting your Spring service to be "authorization-server" as well (serve user identity). If so, I think you should not.
Keycloak (or any other OpenID provider) should be the only authorization-server. Both Spring and client(s) should be configured to use it as so.
To write it differently, Keycloak is responsible for users login and emitting tokens with user ID (subject) and rights (roles or whatever). Other tiers in the architecture (clients & resource servers) get user info from the token and apply relevant security checks (spring security annotations, Angular guards, etc.).
I published a mono-repo for a meetup with minimal sample involving a Spring resource-server and Angular (with Ionic) client talking to a Keycloak OpenID authorization-server. You might find some inspiration browsing it.

Resource Owner Password Credentials with Spring Boot

I have a legacy desktop application that communicates with a Spring Boot server (latest version 2.2.2.RELEASE). I'm using OAuth2 for authentication (provided by spring-boot-starter-oauth2-client). I want to avoid changing the client because is a legacy application. It is capable of collecting the credentials and start the session via HTTP Basic Authentication, and then keep the cookies for the session in the following requests.
Given this scenario, I think best option is to make use the OAuth2 Resource Owner Password Credentials grant. With this, we can exchange the collected credentials by the OAuth2 Tokens. We have two options:
Option 1:
Modify the client application to use the access tokens via the Authorization header. This will require to make an initial call to the Authorization Provider to exchange the collected credentials by the tokens.
Option 2:
Keep using the Spring session and store the information about the OAuth client in the server.
I found this project ALMOST does that: https://github.com/jgrandja/spring-security-oauth-5-2-migrate. It has a client (messaging-client-password) defined with authorization-grant-type: password which will activate the OAuth2 Resource Owner Password Credentials grant in Spring Boot.
It creates an OAuth2 client and stores its information in the session, then Spring is able to use that client in further requests. The problem with this project is it seems to only work as when the OAuth client is used to make HTTP requests (e. g. an endpoint that makes a call to another service) and not provide authentication to the controller. You can find more information about this in here:
Spring Security 5.2 Password Flow
Github related issues: link1, link2, link3
Exception thrown when we try to use the password client as authentication
The natural idea to overcome this is to implement a proxy and use the OAuth2 client in the requests. Well, Spring already offers a proxy solution, the Spring Cloud Gateway. But I don't know to accomplish that with this setup.
Any insights? Am I thinking correctly or should I follow a different approach?

How to get principal - user information from a spring boot restApi which has security configured in to a client spring boot app?

I have two spring boot application. One is Rest and the other one is Spring boot web MVC app which consumes the Rest. The Rest has spring security configured and I want to login/logout from the client app. The client app has nothing but view and controllers to interact with the rest api.
I am using rest template to interact with the api now.
If the client app is not secured so any other anonymous app may do the same, and this is not security, it's a sieve ...
If you want to create a custom authorization/authentication, you can create own protocol and use tokens/JWT (possibly, OpenID or other global technology) and exchange information between applications.
But there is technology to do it all centrally and reliably - OAuth2, and Spring has it 'from the box' - authorization server, resource server, client. The most advantage - multiple applications (clients), one authorization - you create one user and can authenticate it on any client with the same credentials. You can customize it with JWT, and use any data in the access token and as a consequence get any information about principle/authorization.

spring cloud oauth sso without authorize step

I have a spring cloud oauth #EnableAuthorizationServer that uses a jpa backend to store the accounts. I also have a couple of different clients, a website, an intranet and a ionic mobile app.
all the clients have separate client credentials inline in the oauth config block.
i have then tried to use the spring cloud sso to not have to login again.
my problem is that I want to remove the authorize step since all my clients are known to me and i simply want the user to be logged in across all my apps.
is this possible with spring cloud sso?
The authorization happens on the authorization server (so nothing to do with Spring Cloud). A UserApprovalHandler would do what you need, but the default one should work if you just set autoapprove=true (or a pattern matching te scopes you want to auto approve) in the client details. (Assuming your auth server is Spring OAuth.)

Resources