Can spring security parse headers and verify authentication information? - spring

Spring Security is commonly used for authentication and authorization of web applications and web services. While spring can validate users based on credentials_id (user id) and credentails_secret (password) passed through web forms.
What I am looking at is
1) can spring work when these userid and password are passed through http headers.
2) on subsequent requests can spring validate user based on a session id (some thing like jsessionid) passed through http headers?

You can add spring-security module in your project.
passing username and password via http-headers for every request is stateless basic-authentication. Check this example
You can do a stateful authentication: authenticate once, maintain the session.
Check this sample

So, you should write a custom AuthenticationFilter extending referred UsernamePasswordAuthenticationFilter.
Checkout:
Spring Security using HTTP headers

Related

Add additional inner user validation after successful OAuth2 Resource Server JWT check at Keycloak

There is a Spring boot app with endpoints protected with JWT. Token validation is performed by Spring boot OAuth2 Resource Server that checks tokens at Keycloak Authorization Server.
How can additional inner user validation be added to the app after it successfully passes authorization at Keycloak?
So I'd like to build some kind of a chain - if token passes validation at Auth Server then I check the username taken from JWT at local database.
Checking access-token claims against local database for access-control on a resource-server is an easy task inside authentication converters (http.oauth2ResourceServer().jwt().jwtAuthenticationConverter(...) or http.oauth2ResourceServer().opaqueToken().authenticationConverter(...), but this is very inefficient: it is much better to have this DB access once when the token is created on authorization-server, rather than each time it is evaluated during resource-server authorization process (which happens for each request).
All the data required for access-control decisions should be included in the token already. If you need more than standard claims plus the default private claims from your authorization-server, then configure this authorization-server to add the data you need about the user when issuing access-tokens. For Keycloak, this is done with so called "OIDC protocol mappers". Those can issue DB requests, web-service calls and about anything. I have a sample of a mapper adding a private claim with a value from a web-service call in this project.
Once all the data you need is in the token, you just use it as normal in Spring security expressions of your resource-server. Here is a working sample taken from my set of tutorials:
#PreAuthorize("is(#username) or isNice() or onBehalfOf(#username).can('greet')")
In this expression, it is checked that the user either:
is greeting himself (username #PathVariable is equal to preferred_username claim in access-token)
has one of "nice" roles
has permission to greet on behalf of user with preferred_username equal to username #PathVariable (the route is /greet/{username} and this permissions delegation is taken from a private claim added by a mapper like the one in the sample linked above)

Spring Keycloak - How to set principal from JWT access token

I've been at this for about a week now.
I have a use case where I recieve an auth token through the body instead of the header, and because of that Keycloak and Spring don't automatically set the user. (The reason being, with websockets, I can only send the auth token through the body with the initial connection)
I've tried intercepting the call before keycloak and copying the token from the body to the header, but that did not work.
So now I would like to manually authenticate through keycloak (or just manually set the principal user). I have access to the JWT Access Token, but from here I'm not sure how to authenticate with keycloak.
Anyone have any input?
Since there are two Keycloak pieces that could be in play here, I'll start with a clarification:
Keycloak - This is the authorization server that a client will use to obtain a JWT
Keycloak Adapter - This is the thing that configures a Resource Server to integrate Keycloak with Spring Security
I have a use case where I recieve an auth token through the body instead of the header, and because of that Keycloak and Spring don't automatically set the user.
Spring Security 5.1 ships with built-in support for JWT-based access tokens, so you may not need to use the Keycloak Adapter for what you are wanting to do.
When using Spring Security's built-in support, you can configure the DefaultBearerTokenResolver to look in the body:
#Bean
public BearerTokenResolver bearerTokenResolver() {
DefaultBearerTokenResolver resolver =
new DefaultBearerTokenResolver();
resolver.setAllowFormEncodedBodyParameter(true);
return resolver;
}

How to implement JWT with Keycloak in Spring boot microservice acrhitecture?

I have read some articles for Keycloak spring implementation (eg: easily-secure-your-spring-boot-applications-with-keycloak) but no one mention how to use with JWT.
I have created zuul api gateway and add Keycloak adapter as described in the previously linked article. That's ok, but I want to use JWT with keycloak.
Mentioned elsewhere set the client access type to bearer-only and the session strategy to NullAuthenticatedSessionStrategy. That's enough or need something else for JWT?
So my questions:
How do I configure client on Keycloak admin for JWT?
How do I configure Keycloak in backend config file for JWT?
How do I configure Keycloak adapter for JWT?
How do I pass user info to microservice? Create filter in gateway? But how I get user info from request?
Keycloak access token is a JWT. It is a JSON and each field in that JSON is called a claim. By default, logged in username is returned in a claim named “preferred_username” in access token. Spring Security OAuth2 Resource Server expects username in a claim named “user_name”. So, you need to create mapper to map logged in username to a new claim named user_name.
In order to provide access to client (micro-service), respective role needs to be assigned/mapped to user.
In your spring boot application, then you need to configure connection to keycloak server, providing, auth url, token url, scope, grant-type, client-id and client-secret.
Afterthat, your app be able to parse JWT token, you need to create some JwtAccessTokenCustomizer. This class should extend DefaultAccessTokenConverter and implement JwtAccessTokenConverterConfigurer classes. The main logic lays in public OAuth2Authentication extractAuthentication(Map<String, ?> tokenMap) method.
Then you need to configure OAuth2 Resource Server to provide access for other micro services. For that you define here - Oauth2RestTemplate Bean.
And in the end, secure your REST API, via the standard configuration Component.
So, you can see that, it is a large work, and couldn't be described with code, show some of your work, divide it to the chunk, and ask interesting your questions.

spring security spnego ldap jwt

I have a complex situation where I need to implement a security for web app on tomcat 8 that serve both static html and rest services. the app is spring mvc application (no spring boot)
the authntication ( sso ) process will go as follow:
if user jwt not exist in http header then authonticate with ldap, getting user authorities from db and create jwt back to user.
if jwt exist in header, skip ldap filtering , extract the user authorities from token.
I was thinking of first servlet filter that uses spnego library and get the windows domain name (user name to use in ldap) that filter will also check to see if ldap authontication is needed ( if token not provided) and pass it back to spring filter chine through http params..
I'm struggling to implement he ideal.
please help.
thanks
As I know, there is support for LDAP in spring security, might be it will help you.
Other than that, if you want to write your own filters then you have to add those in spring security filter chain.

Spring Security custom validation without using user password involved

I was wondering if in Spring Security is possible to lock all endpoints of a rest api, and to do a login by doing a custom validation without using the username and password at all.
It is like create a custom validation method that receives a token and not user/pass. The method will then validate the token with third party that has already validated the caller.
This sounds familiar to OAuth2 only that the backend API needs to be secure by spring, and at the same time it is not the OAuth2 client:
We are building a login feature.
We have a client (mobile app), backend (REST like endpoints Spring MVC), and an AuthProvider for OAuth2/OpenIdConnect flows.
The OAuth/OpenIDConnect flow happens only between the mobile and OpenIDProvider. (an initial call happens from mobile to backend to provide some details for oauth flows)
Once the authorization succeeded, the mobile app receives an auth_code, and only then the backend is called from the app to "Login" which means validate the auth_code, exchange for access_token, and create user session. (we need to have a session).
As you see backend kind of "login" in the sense that needs to receive the auth_code only, and validate it with the AuthProvider before creating a session.
Thank you very much!
Any comments, or references are very appreciated.
Spring Security determines if a user is authenticated by looking at the SecurityContext in the SecurityContextHolder. This means you can authenticate the user however you like using the following:
boolean userIsAuthenticated = ...
if(userIsAuthenticated) {
Authentication request = new UsernamePasswordAuthenticationToken(name, password);
Authentication result = ...
SecurityContext context = SecurityContextHolder.createEmptyContext();
context.setAuthentication(result);
SecurityContextHolder.setContext(context);
}
Spring Security is a very flexible framework that publishes a variety of interfaces that allow the user to customize the behavior as need be.
I'd recommend the following resources to learn how to go about this:
Architecture Deep Dive in Spring Security
Spring Security Custom Authentication Provider
Spring Security Custom AccessDecisionVoters
Spring Security Reference Documentation

Resources