Spring OAuth2 OAuth2RestTemplate and resource owner password - spring

I'm trying to figure out how to have my Spring OAuth2Client use the resource own password scheme when authenticating to my Authorization server using Spring OAuth2. I don't get what the documentation states:
If you desparately need password grants to work from a Java client, then use the same mechanism to configure your OAuth2RestTemplate and add the credentials to the AccessTokenRequest (which is a Map and is ephemeral) not the ResourceOwnerPasswordResourceDetails (which is shared between all access tokens).
How do I do this? Since I'm building both the authorization server and the client my client is a trusted source and I do not need to go through the auth code flow.
I saw this answer: Spring Security Oauth2 - Adding credentials to the AccessTokenRequest
But, I'm not exactly clear how to achieve this so that I don't have to go through the redirect. Can you do this through a basic auth header?
Update:
I think I got it working
I create a ResourceOwnerPasswordResourceDetails and create a new ResourceOwnerPasswordAccessTokenProvider
Then get a token using the credentials and set the token in the injected oauth rest template.
OAuth2AccessToken token = accessTokenProvider.obtainAccessToken(details, request);
restTemplate.getOAuth2ClientContext().setAccessToken(token);
Is this correct?

Related

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 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

How one can use other oauth2 providers like FB, Google in an existing jwt authentication system

I am new to spring boot and trying to implement oauth2 client with facebook as oauth2 provider.
I already have a traditional JWT token authentication in place which is configured with in #EnableWebSecurity with default authentication manager and custome JWT token generator.
is it really required to configure AuthorizationServer and
ResourceServer in above scenario?
if not then why my code always returns me only Code and state from facebook to call back URL.
Please have a look into the code here
Oauth2 = Authorization delegation protocol NOT an authentication one.
If you want to use FaceBook and Google as identity provider then you must go with an identity federation protocol, ie OpenId Connect (OIDC).
This last add an authentication layer (using JWT id token) above oauth2 authorization layer.
Regarding more specifically your question (which is not very clear) about the spring security configuration part , it seems that the current oauth2 server implementation (AuthorizationServer and ResourceServer you're talking about are part of it) is not suitable as it is to implement an OIDC identity provider)
Regarding the code and state returned to the callback URL, it's part of the oauth2 authorization code flow and it's perfectly normal, you then have to exchange the retrieved code against an access token using the authorization server token endpoint.
(state is just here to allow to transmit an information for example a tenant id, across the oauth2 whole flow).
Here is really well written oauth2 vulgarization article.

Spring boot, security starter and OAuth2 client

I'm using Spring Boot with web and security starter dependencies, and spring-security-oauth2. I'm trying to secure a REST API with a remote (Openstack Keystone) OAuth2 provider.
So far I've managed to correctly fetch an access_token but when it comes to getting the user information I get a 404 not found, as it seems that the OS provider expects the access_token to be provided in the request parameters.
I can't figure out how to persuade the OAuth2RestTemplate class to append the access_token to the security.oauth2.client.resource.user-info-uri endpoint.
Figured out that setting security.oauth2.client.client-authentication-scheme to query will make the RestTemplate append the access_token to the subsequent requests for user information.

Resources