Token authentication based with spring security - java

I am trying to enable token based authentication for a HTTP api with spring security.
Looking around i see answers about implementing the filters and the handlers like
Spring Security authentication via token
Spring Security 3.2 Token Authentication
There is a pretty interesting KeyBasedPersistenceTokenService class.
Is there no filter or the rest of the elements needed to build up the authentication mechanism in spring security?

The Token interface in Spring Security is pretty abstract - you would need to provide your own implementation to carry actual authentication information, and your own endpoints for issuing tokens to authenticated users or clients, as well as the filter you mention to process the token on protected resources (one of the links you posted suggests using AbstractPreAuthenticatedProcessingFilter and that is correct). There isn't really a one-size fits all solution.
You might be better off with OAuth2 since it's a standard and supported separately in Spring OAuth. At least you get all those features out of the box that way.
Another interesting token implementation is Github's "secure http" - they give you a token and you use it as a password in HTTP Basic authentication (widely supported client-side and also available out of the box in Spring Security). You would only have to plugin a UserDetailsService (and hook it up to some token issuing UI) if you were implementing it in Spring Security.

Related

Keycloak and SpringBoot

I started playing with Keycloak, but I have a question. While reading articles, I always found examples where a client (let's say Angular) is logging in on Keycloak, it gets a bearer and then it send the bearer to the SpringBoot application. The backend, so, validates that the bearer is valid and, if so, it allows you accessing the desired endpoint.
But it's not enough in my opinion. I don't need just to login, I would need the entire functionality - let's say I have a backend application and I need a user. I could have a basic todo-application, how do I know for which backend user I am actually accesing an endpoint?
Straight question: how can I bind my own backend user (stored in the DB from backend) to the one from Keycloak?
What is the best way to do it? The only thing that I found online and into the Keycloack documenation is that I could move the logic of logging in from client (Angular) to backend (SpringBoot). Is this the way to go?
Imagine like I'm creating my manual /login endpoint on backend on which I would then call the Keycloak server (Keycloak REST client?) and I would pass myself (as a backend) the bearer to the client.
Please help me with an explanation if I'm right or wrong, what's the best practice, maybe help me with an online example, because I just found out the too easy ones.
OpenID tokens are rich
Keycloak is an OpenID provider and emits JWTs. You already have the standard OpenID info about user identity in the token (matching requested scopes), plus some Keycloak specific stuff like roles plus whatever you add with "mappers".
All the data required for User Authentication (identity) and Authorization (access-control) should be embedded in access-tokens.
How to bind user data between Keycloak and your backend
In my opinion, the best option is to leave user management to Keycloak (do not duplicate what is already provided by Keycloak). An exception is if you already have a large user database, then you should read the doc or blog posts to bind Keycloak to this DB instead of using its own.
Spring clients and resource-servers configuration
I have detailed that for Spring Boot 3 in this other answer: Use Keycloak Spring Adapter with Spring Boot 3
In addition to explaining configuration with Spring Boot client and resource-server starters, it links to alternate Spring Boot starters which are probably easier to use and more portable (while building on top of spring-boot-starter-oauth2-resource-server).
I Also have a set of tutorials from most basic RBAC to advanced access-control involving the accessed resource itself as well as standard and private OpenID claims from the token (user details) there.
Tokens private claims
For performance reason, it is a waste to query a DB (or call a web-service) when evaluating access-control rules after decoding a JWT: this happens for each request.
It is much more efficient to put this data in the tokens as private claims: this happens only once for each access-token issuance.
Keycloak provides with quite a few "mappers" you can configure to enrich tokens and also allows you to write your own. Sample project with a custom Keycloak mapper here. This is a multi-module maven project composed of:
a custom "mapper" responsible for adding a private claim to the tokens
a web-service which exposes the data used to set the value of this claim
a resource-server reading this private claim to take access-control decisions
The simplest way to do it is to consider that the job of storing users will be delegated to your Keycloak server. But you can implement some roles and checks manually with in-memory or any database of your preference too.
I invite you to follow some documentation about OAuth 2 and Keycloak, to make requests to get a valid token for a time period and to make others request inside that time period to get datas. You can use CURL to make requests or web/software tools like Postman.
Be careful, a lot of Keycloak Adapters are deprecated ones since some months.
I would echo BendaThierry's comments. Look into OAuth2 and Keycloak. The Bearer token you receive from Keycloak will have user information in it (typically in the Claims). This way you can have user preferences or features in your backend without needing to manage the authorization and authentication that Keycloak does.
There are lots of great resource include Spring's website tutorials (like https://spring.io/guides/tutorials/spring-boot-oauth2/) and Baeldung (https://www.baeldung.com/).

Authentication between Keycloak and Backend-Services

We use Keycloak to secure our Spring Boot based Java Backend Services. Every endpoint is secured and a bearer token is expected inside the authorization header for each request. Keycloak then validates and verifies the token. So far so good.
During the registration process inside Keycloak (we use the authorization code flow), we have different use cases in which Keycloak have to approach our Java Backend for instance to validate an access code. I would love to use the same mechanism to secure those endpoints that are exclusively approached by Keycloak. I am wondering if it is a bad idea to use a keycloak user to send an http from a keycloak spi to our spring boot backend and then ask keycloak if the given JWT is valid. This feels like a chicken egg problem.
This feels like a common problem. What is the recommended authentication/authorization process for this kind of service to service communication? I was thinking about a technical keycloak user, that is managed inside keycloak for this purpose. I am aware of the Keycloak REST API that provides an endpoint to retrieve a token for credentials. Since I am implementing custom SPIs in keycloak, I am looking for a way to generate a token programmatically. I was able to find the right Keycloak library. Does someone know how to do that?
Here are my question:
How can I secure requests that I would like to send from keycloak to our backend?
How can I generate a Token inside Keycloak without using the Keycloak REST API (since I am implementing custom Keycloak SPIs)
Is there another way to secure my backend for technical users without using keycloak?
Best regards
Michel

Custom login form - Spring Security

Does any of you have some example of Custom Spring Security Login form using REST Api? I am actually trying to create my own, and the problems I'm facing are:
How should be named classes, is it User and Role? Cuz I seen many different versions of it.
Where should I post JSON file with login and password?
How should it look like?
Thanks in advance for all answers and examples of your code (github or something).
REST APIs are usually stateless. It does not know something about a session. So i think you're looking for an basic auth to protect your API.
Or you could use openid connect and check the roles based on a token. This would give you more flexibility for pre conditions and post conditions processing a service call.
Here is a good example of openid connect with spring boot and google implementation. Other provider are adaptable. Baeldung - Spring Security openid connect
If you're just looking for a simple solution with basic auth, take a look here
Baeldung - Spring Security basic auth
yes, you can use form login and rest API together, but that means that your rest API isn't going to be stateless, it means that a session will be created and rest APIs are usually stateless, that's why you have to use basic auth, jwt, etc when creating a rest API, but if you really want to use rest API with form-based authentication, I made an example for you, check this link
This example uses Spring Boot, Spring MVC, H2, Spring Security with custom form login, Spring Data Jpa, but again it's not recommended to use form login for rest API.
Regarding to your questions
How should be named classes, is it User and Role? Cuz I seen many different versions of it.
It's up to you
Where should I post JSON file with login and password?
If you are using spring security form-based authentication, there no need to post a json

Spring Security - Rest API

I am new to spring security
I have a front end application built using vuejs which calls spring rest api to interact with the backend system.
I have a login page where user enters the password. I want to be able to authorise the user if his login is correct and for the subsequent request authorise him with rememberMe token.
I know there is a lot of information available on the topic but
What is the right way to implement?
Should i use basic authentication ? If I am using basic authentication , how should i set up remember me along with basic authentication?
Should the authentication be handled in post call instead of using a auth filter?
Here are two scenario
If your front-end is built on any frontend framework and it's not dependent on any Server Pages(e.g JSP, Freemarker, velocity) or you want your frontend application to connect to your backend application through web services(Rest web service or SOAP web service) then you need to implement your own token base authentication with help of spring security instead of Basic Authentication of Spring security.
Else you should go with Spring Security Basic authentication, for implement Remember-me with spring security, Spring Security provides two implementations for Remember-Me :
1: Simple Hash-Based Token Approach: It uses hashing to preserve the security of cookie-based tokens
2: Persistent Token Approach: It
uses a database or other persistent storage mechanism to store the
generated tokens
Here is spring remember-me doc for it

java mvc authorization without spring security

My task is to use a send request and then to get some XML.
example:
request: /api/ext/data.xml
response: some XML
The application uses Spring MVC, so I just wrote controller method, and everything works OK, but I also need to implement authorization. This app does not use Spring security.
What should I do? Should I use session to save User authorization data?
You should still look at Apache Shiro and/or Spring Security. However Spring Security (and container security for that matter) are not so friendly for REST API security. For Spring you will need to implement a custom AuthenticationEntryPoint to avoid the redirect on 403. Shiro might be a little easier for REST API.
If you want to do it yourself w/o dependencies or complexities you should look into writing a Servlet Filter and/or leverage container security. A compromise might be this SecurityFilter project. However if you need Roles, ACLs etc... you should seriously reconsider Shiro or Spring Security.
And what about implementing your own HmacSha1 model (signed requests) as Amazon Web Services do?
Basics: Client signs the request with a Secret access key (SAK) and expire data, obtaining an hmac code.
Then client sends via POST the request plus some headers like hmac code and expire data and whatever you need. The server then gets your request in the controller (or interceptor), signs it with your SAK and expire time, and compares obtaining hmacs to validate user.

Categories