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?
Related
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.
is possible create authorization server for PKCE authentication in current version of spring security?
I did research and I found out this authorization server project https://github.com/spring-projects-experimental/spring-authorization-server but there is no usable sample for that project.
I also find out that spring recommends Keycloak as authorization server, but it is not fit for my case.
We need be able fetch and verify user against remote service, and then use authorization server only for generating and verifying jwt tokens. In my knowledge Keycloak should holds also users right? So the best solution would be custom spring standalone authorization server. Is it possible in some way? Thank you!
You may have a look to this project: CloudFoundry User Account and Authentication (UAA) Server.
UAA is a (Spring MVC) component of Cloud Foundry but it could be used as a stand alone OAuth2 server. It can support external authentication service. And there is a Pull Request that implements PKCE: https://github.com/cloudfoundry/uaa/pull/939 (not yet merged, but under review).
You can find an example on how to use UAA on baeldung.com.
As far as I know, Spring framework has one more implementation of the authorization server. It is a part of spring-security-oauth project. But this project was moved into maintenance mode.
According to this migration guide, the new authorization server project (that you have already found) will be created to change the legacy solution.
From my point of view now there are several possible options:
Using old legacy spring-security-oauth. More examples with old auth server
Using external services like Keycloak, Auth0, Okta and etc
I want to implement in backend rest safely in oauth2 + jwt.
I want to implement the following authentication flow in spring boot, but I am not sure how to do it:
1. The user is authenticated.
2. That request is received and with that login and password a ws that validates the credentials is attacked.
3. If it is correct, a series of data and permissions are searched in the database
4. If it is correct, access is granted and the jwt token is generated
I'm lost with this and as much as I read I can't know how I can do it.
Any manual or post I can follow?
Are you running your own (a custom) Auth server or is the plan to allow users to authenticate via a provider such as Google, Facebook etc? If its the later, then you cannot expect to receive user / password credentials at all so you might have misunderstood the OAuth flow. You will typically receive an 'Authorization code' from the provider (e.g. Google).
Also, what do you mean by "a ws that validates the credentials is attacked"?
This Google use-case diagram depicts a common flow. It's part of this guide.
Either way, Spring Boot does not itself deal with OAuth / security, but it has a tight
integration with Spring Security which is a good security framework to use, especially as you're already using Spring. Spring Security can handle OAuth, JWT etc.
A couple of guides that may help to get you started:
https://www.baeldung.com/spring-security-oauth-jwt
https://spring.io/guides/tutorials/spring-boot-oauth2/
I have an architecture where my user application wants to use a basic authentication when accessing a spring service. This service has to use a Keycloak instance to verify the user/pass of the user application. I don't succeed to configure it (and don't know if its possible).
Yes, it is possible. Keycloak has Spring Security adapter that can be configured for Client and/or Resource Server.
https://www.keycloak.org/docs/latest/securing_apps/index.html#_spring_security_adapter
And also a working example here:
https://github.com/keycloak/keycloak-quickstarts/tree/latest/app-authz-spring-security
I have updated the jhipster generator from version 1 to version 2. In the previous version we had to choices of authentication when generating a new project. We had the choice between Cookie authentication and Token authentication (with OAuth). This was very clear for me. But in version 2.1.1, we have now three choices :
1 > HTTP Session Authentication (stateful, default Spring Security mechanism)
2 > OAuth2 Authentication (stateless, with an OAuth2 server implementation)
3 > Token-based authentication (stateless, with a token)
I want to used the authentication both for web and mobile app (ionic-framework), which one to one between 2 and 3 ? Is this choice make my app scalable using clusters ?
Thanks
you will the basic info about jhipster authentication type here
http://jhipster.github.io/security/
from my personal experience in ionic-framework working with REST api of jhipster, I can say that don't use HTTP Session Authentication for mobile app (ionic-framework) because mobile apps don not play along with cookies in general which HTTP Session Authentication depends upon.
Both Oauth2 and JWT work fine with ionic hybrid app
HTTP Session Authentication
This is the "classical" Spring Security authentication mechanism, but we have improved it quite significantly. It uses the HTTP Session, so it is a stateful mechanism: if you plan to scale your application on multiple servers, you need to have a load balancer with sticky sessions so that each user stays on the same server.
OAuth2 Authentication
OAuth2 is a stateless security mechanism, so you might prefer it if you want to scale your application across several machines. Spring Security provides an OAuth2 implementation, which we have configured for you.
The biggest issue with OAuth2 is that requires to have several database tables in order to store its security tokens. If you are using an SQL database, we provide the necessary Liquibase changlog so that those tables are automatically created for you.
As Spring Security only supports OAuth2 with SQL databases, we have also implemented our own MongoDB version. We generate for you all the OAuth2 implementation for MongoDB, as well as the necessary MongoDB configuration.
This solution uses a secret key, which should be configured in your application.yml file, as the "authentication.oauth.secret" property.
JWT authentication
JSON Web Token (JWT) authentication, like OAuth2, is a stateless security mechanism, so it's another good option if you want to scale on several different servers.
This authentication mechanism doesn't exist by default with Spring Security, it's a JHipster-specific integration of the Java JWT project. It is easier to use and implement than OAuth2, as it does not require a persistence mechanism, so it works on all SQL and NoSQL options.
This solution uses a secure token that holds the user's login name and authorities. As the token is signed, it cannot be altered by a user.
The secret key should be configured in the application.yml file, as the jhipster.security.authentication.jwt.secret property.