SpringBoot command-line application with OAuth2 - spring

I'm working on a SpringBootApplication that implements CommandLineRunner. We are usign keycloak as our OAuth2 provider with a public client.
We would like to trigger SSO when someone uses the build from a CLI.
ie.
$ sampleclitool dosomething
... Redirecting to SSO... waiting for access token... etc..
... SOME_USER_NAME is logged in.
... Doing something!
Ive been using Spring Security in other microservices and am trying to figure out how to follow the same "flow".
Use the CLI (any command).
Check if user is authenticated.
If user is not authenticated, open SSO authentication in default browser.
If user is authenticated, continue.
CLI makes requests to other services (microservices, hosted by me).
Authorization header (JWT) is attached to those requests.
The exact trigger for auth isn't important to me, but the end result is that who ever is using the CLI can login to it from the browser, then make request to protected services.
I cannot for the life of me, without some selenium integration, think of a way to achieve this flow. I'm not sure if there are some clever mechanisms in Spring Security that I can hook into.
Using SpringBoot 3.0.1 and WebFlux.

Related

Implement Keycloack Authorization server using Spring Security 5 OAuth2

I've written a software system that uses Spring Cloud Netflix. Due to Spring Security 5 not offering support for writing an Authorization Server (pls shout out here https://github.com/spring-projects/spring-security/issues/6320) I need to write my own Authorization server. I want my application to permit Social login and username/password registration, have a custom login page but also use keycloack. I don't even know from where to start, if you have any documentations or code samples please provide.
You can use the cas project. By using the overlay it is easy to set up and to customize:
https://github.com/apereo/cas-overlay-template/blob/master/README.md
It serves a frontend where your user can be redirected to and can login. After successful login, the user is redirected back to your web page. The frontend is completely customizable.
It supports all kinda of authentication providers like keycloak, database or Google/Facebook.
After basic setup you just add the dependency inside the gradle file, configure your keycloak/database/... in the application.properties and can start using it as authentication server.
It fits perfect into a microservice landscape and is curated by professionals implementing security best practice.
https://apereo.github.io/cas/6.1.x/planning/Getting-Started.html

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 integrate keycloak in Spring Boot with a different context root and reverse proxy

We are currently developing a microservice application using Spring Boot 1.4 and Keycloak 2.5.0 (configured as openid-connect service) using the Keycloak Spring Adapter (not the Spring Boot adapter).
All of our microservices are put behind a load balancer and an additional reverse proxy as the application will be hosted on an existing domain behind a context root (so the root of our application is http://foo.bar/foobar/ and the rest services are http://foo.bar/foobar/rest/).
We are facing a couple of problems with Keycloak in this given scenario:
Keycloak forward to /sso/login if a sign-in is needed. This is in our case unwanted behaviour because http://foo.bar/sso/login will not exist. I have found a way to change the forward but there is no way to make Keycloak listen to the same url; we end up with a 404 in this case.
After signing in, Keycloak redirects back to the /sso/login url with the correct tokens, but if this is not the same server, the request fails and it redirects us to http://foo.bar/. Since every microservice exposes /sso/login, this can be in fact a completely different server.
If keycloak is hosted on the same domain, we end up in a redirect loop. We would also like to have Keycloak hosted on the same domain and on the context root http://foo.bar/foobar/auth/ .
We've already tried using the "token-store": "cookie" but this did not resolve the problem.
Is there a way to resolve these problems or is Keycloak maybe not the correct solution for our use-case ?
Update 05/05/2017:
Move my answer from here to an answer
We are now up and running with Keycloak so I'll briefly explain what we did. The front-end of our application runs Angular2 and we created a custom login page in the Angular application itself (so it's not a theme for Keycloak) which will directly query the Keycloak API for an OAuth2 Bearer token. The front-end will send this token on each request in the Authorization header (as per the OAuth standards).
On the service side we have configured keycloak as a bearer-only solution (bearer-only: true in the keycloak.json), this way the application just returns a 401 or a 403 instead of forwarding to the login page.
Using this configuration the user will never see anything from the /sso/login page and there is also no redirect issue anymore.
TLDR; the use-case I described was also not realistic, calling a REST URL and then forwarding to a login page is kind of bad stuff :)

Spring Security with SAML Token for REST Service

I'm looking for a simple example of a spring security configuration (Java config preferred) on how I can secure my REST Services with Spring-Security and SAML.
There's an Web Application Firewall in front which will only pass requests which contain a valid SAML Token or otherwise redirects to IDP to get one. So I don't have to look if the user is logged in or redirect the user if not so to the IDP.
The only thing I'll need to do is allow only authenticated requests to all REST Services, read the user from SAML-Token and check that the Token is from Airlock.
Later I'll need to add ACL support for more fine granular rights of the user on specific services but I'm already lost with the first part of the integration work in spring security. Any help would be welcome :)
the magic happens here: https://github.com/spring-projects/spring-security-saml/blob/master/core/src/main/java/org/springframework/security/saml/SAMLProcessingFilter.java
in attemptAuthentication(), it gets the SAML message, parse it and gets the token (SAMLAuthenticationToken). Then it tries to authenticate the user: authenticate(token);

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