how to extend existing Keycloak API resource in my SPI? - keycloak

I want to make an SPI that adds an API /users/{userId}/mypath under the user resource. But I can't just simply update UserResource.java to add my methods since my SPI should be plugged in as a wildfly module. How to extend UserResource.java in my SPI?

Related

Spring boot oauth2 integration with keycloak using Spring webflux along with multi-tenancy

I need to implement Authentication & Authorization using spring boot oauth2 with keycloak as a provider.
I also need to support muti-tenancy. I tried example with authentication using spring-boot-starter-auth2-client to authenticate, but not able to add multi-tenancy.
When I used spring-boot-starter-auth2-client, I need to configure hardcode keycloak urls(specific to one tenant) in properties and not able to support multi-tenancy.
I also analyze spring-boot-starter-auth2-resouce-server, but not clear. I understand that resouce server use for validation of token and expiry.
Note: I don't want to use keycloak adapter library which is provided by keycloak.
Could you please help me -
Where need to use spring-boot-starter-oauth2-client and spring-boot-starter-oauth2-resouce-server?
Is spring-boot-starter-oauth2-resouce-server also use to authentication?
How to authenticat user using spring-boot-starter-oauth2-client and pass to spring-boot-starter-oauth2-resouce-server for authorization.
How to implement multi-tenacy e.g. take tenant id from url and redirect user to tenant specific keycloak login page.
I tried some example but won't succeed, working example will be helpful with -
Spring Webflux + spring-boot-starter-oauth2-client+ spring-boot-starter-oauth2-resouce-server + multi-tenancy + keycloak as a provider.
Thanks & Regards,
Pravin Nawale
tried some example found on internet, but didn't work.
This question should not be answered because:
it is actually a container for many questions
quite a few are way too wide or lack precision.
But as it seems to be a first question... (break it down next time, give more details and edit your question when you get comments asking precisions)
1. Where need to use spring-boot-starter-oauth2-client and spring-boot-starter-oauth2-resouce-server?
This one is important to start with as I suspect you lack OAuth2 background, specifically regarding involved parties and how it is implemented with spring-security:
spring-boot-starter-oauth2-client is to be used with OAuth2 clients:
apps serving UI with oauth2Login (#Controllers with methods returning template names)
apps consuming REST APIs with auto-configured Spring client: WebClient, #FeignClient, RestTemplate
spring-boot-starter-oauth2-resouce-server is to be used with resource-servers: apps serving REST APIs (#RestController or #Controller with #ResponseBody)
Now, if your app has controllers for both the resources and the UI to manipulate it (with Thymeleaf or any other server-side rendering engine), then define two different security filter-chains: one for each, ordered, and with securityMatcher in the first in order to limit the routes it applies to (the second being used as fallback for unmatched routes). Sample in this answer (the sample is for servlet, but it's the exact same principles): Use Keycloak Spring Adapter with Spring Boot 3
2. Is spring-boot-starter-oauth2-resouce-server also use to authentication?
OAuth2 requests should be authorized with an Authorization header containing a Bearer access-token.
The client is responsible for acquiring such an access-token from the authorization-server before sending requests to resource-server.
Your question is not quite clear but here are a few statements which could answer:
resource-server should return 401 (unauthorized) and not 302 (redirect to login) when authorization is missing or invalid => do not configure oauth2Login in resource-server filter-chain. Again, this is client business
resource-server is responsible for resources access-control: check that access-token is valid, that the user has required authorities, etc.
3. How to authenticat user using spring-boot-starter-oauth2-client and pass to spring-boot-starter-oauth2-resouce-server for authorization.
This question is not focused enough to get a single answer: what kind of client? what kind of request? context?
I see three main cases here:
the UI is rendered on Spring server with Thymeleaf, JSF, and alike => use spring's oauth2Login and refer to its documentation to overrides defaults and implement your authorization-server selection logic
the UI is rendered in the browser (Angular, React, Vue, ...) and you are ok to make it an OAuth2 client => find a certified client lib for your framework and implement the logic in the client (angular-auth-oidc-client, for instance, supports multi-tenancy)
the UI is rendered in the browser, but you prefer to implement the Backend For Frontend pattern to hide tokens from browser, then choose a BFF (like spring-cloud-gateway with tokenRelay filter) and refer to its doc for implementing your logic in it
If that can be of any help, I have:
here a tutorial for configuring an app with a Thymeleaf UI client and REST API
there a sample repo with an Angular workspace (app configured as OIDC client + API client lib generated from OpenAPI spec) and spring-boot resource-server (using servlet, but this makes no difference to the client).
4. How to implement multi-tenacy e.g. take tenant id from url and redirect user to tenant specific keycloak login page
Note
One of key principles of OAuth2 is that identities (tokens) are emitted (issued) by trusted 3rd parties (authorization-servers) => you must configure the list of issuers your resource-servers can trust (and clients can fetch tokens from). This list is static (loaded with conf at startup).
Accept identities from various issuers on the resource-server
This is done by overriding the default ReactiveAuthenticationManagerResolver<ServerWebExchange> in your SecurityWebFilterChain configuration: http.oauth2ResourceServer().authenticationManagerResolver(authenticationManagerResolver)
I provide with thin wrappers around spring-boot-starter-oauth2-resource-server which support multi-tenancy just by defining properties. Complete sample there:
Instead of spring-boot-starter-oauth2-resource-server (which is a transient dependency):
<dependency>
<groupId>com.c4-soft.springaddons</groupId>
<artifactId>spring-addons-webflux-jwt-resource-server</artifactId>
</dependency>
Instead of all your resource-server Java conf (unless you want access control from configuration and not with method-security, in which case, you'd have to define an AuthorizeExchangeSpecPostProcessor bean here). Of course, you'll have to add here a client filter-chain with a restrictive securityMatcher if you also serve UI client with oauth2Login:
#EnableReactiveMethodSecurity
#Configuration
public class SecurityConfig {
}
Instead of spring.security.oauth2.resourceserver properties:
com.c4-soft.springaddons.security.issuers[0].location=https://localhost:8443/realms/realm-1
com.c4-soft.springaddons.security.issuers[0].authorities.claims=realm_access.roles,resource_access.client-1.roles,resource_access.client-2.roles
com.c4-soft.springaddons.security.issuers[1].location=https://localhost:8443/realms/realm-2
com.c4-soft.springaddons.security.issuers[1].authorities.claims=realm_access.roles,resource_access.client-1.roles,resource_access.client-2.roles
# Comma separated list of routes accessible to anonymous
com.c4-soft.springaddons.security.permit-all=/api/v1/public/**,/actuator/health/readiness,/actuator/health/liveness
# Fine-grained CORS configuration can be set per path as follow:
com.c4-soft.springaddons.security.cors[0].path=/api/**
com.c4-soft.springaddons.security.cors[0].allowed-origins=https://localhost,https://localhost:8100,https://localhost:4200
# this are defaults and can be omitted
com.c4-soft.springaddons.security.cors[0].allowedOrigins=*
com.c4-soft.springaddons.security.cors[0].allowedMethods=*
com.c4-soft.springaddons.security.cors[0].allowedHeaders=*
com.c4-soft.springaddons.security.cors[0].exposedHeaders=*
If you don't want to use "my" wrappers, just copy from the source, it is open.
Redirect the user to the right authorization-server from client UI
As explained at point 3., this depends on the kind of client, used framework and if BFF pattern is applied or not
5. I tried some example but won't succeed, working example will be helpful with - Spring Webflux + spring-boot-starter-oauth2-client + spring-boot-starter-oauth2-resouce-server + multi-tenancy + keycloak as a provider
With all the elements above and linked resources, you should have enough to find your own path

Extend authentication with custom licenses entities?

I'm using Keycloak as an auth server behind an Nginx reverse proxy.
Leveraging the multi-tenancy and multi-roles suites my needs but I'd like to extend the authentication flow with some custom user-properties that would be ideally stored in an alternative schema/database.
These could be exemplified by:
A global subscription with an expiration date associated with one or more tenants/realms.
A license with expiration date associated with each user inside the same tenant/realm.
...
From what I've understood I could exploit a custom Authenticator SPI that checks these fields based on the user_id and add it to a custom Authentication Flow defined for each separate client inside my pool. Is this the correct use case or is there a better general approach to apply?

Create Interceptor class for WSO2 API Manager

I am new to WSO2 AM and I would like to create interceptor class for APIs that are published on my company's server on API Manager. The thing is that I need to create a solution for DRM (Digital Rights Management), to do so I need to create the class that intercepts all calls to my APIs and do some control check from the JSON that arrives with the user token and some user's parameters.
Until now I was searching for the answers on google for weeks, but didn't find anything useful. Can someone help me with this?
API request/response interceptors in WSO2 API Manager are called handlers. APIM comes with a set of default handlers for authentication, rate limiting, analytics etc. and you can define your own custom handlers as well. Follow these docs for details.
APIM 2.6.0: https://docs.wso2.com/display/AM260/Writing+Custom+Handlers
APIM 3.0.0: https://apim.docs.wso2.com/en/3.0.0/Learn/APIGateway/Handlers/writing-custom-handlers/

Custom Authenticator for OpenID Keycloak realm

I am currently evaluating keycloak as central Identity Manager for multiple a backend with multiple REST services (Resteasy/Wildfly).
After a lot of trial and error and reading the docu, I have succeeded in succesfully making an openid connect login into my custom keycloakrealm (analogue to this post http://blog.keycloak.org/2015/10/getting-started-with-keycloak-securing.html)
I can see the acces token + id_token coming in the response and are able to make requests to the REST services by passing these tokes.
However I can only authenticate using the credentials of the users defined in keycloak itself. However, in our reallife case, the users reside in SAP and are unknown to keycloak.
We do, however have a javalibrary for authenticating these users over the SAPJCO connector.
Can anyone please tell me how to configure keycloak to use a "custom authentication" module for the actual authentication?
Is implementing a custom authenticator SPI (https://keycloak.gitbooks.io/server-developer-guide/content/v/2.1/topics/auth-spi.html) the way to go? If not, what wuold be a possible solution???
Hope you guys can help!
Reagrds,
Kim Zeevaarders
The Netherlands
If you can access the SAP users details via the SAPJCO connector then you could write a custom Federation Provider. The provided example is rudimentary but it give the basic idea and maven dependencies.
In a nutshell you will need to extend org.keycloak.models.UserFederationProvider and provide methods for obtaining user details, validation of credentials and searching by attributes. In your case you would use your SAPJCO connector to fulfil each of these functions against your existing user base.
Update 30 May 2018
The User Federation SPI was replaced with a new User Storage SPI in release 2.5. Migration Notes are available here

combining spring security 3 with jersey rest api

I have a scenario where I am trying to combine spring security with jersey for my REST API.
My need is rather complicated (I think) and it is as follows:
Spring security is being used to intercept urls and forcing basic authentication in order to access a REST resource. This seems to be ok as I am using http client to test this.
However what I want to do is somehow access the User object that is loaded to check some additional permissions that hang off the user (a map object with boolean flags to indicate if object properties are visible or not). The code that does the loading works, but after spring authenticates how do I then access the User object in the actual REST Resource method itself?? Is this possible?
So the steps are:
1) Client makes a REST API call
2) Spring intercepts URL checks username and password supplied in the http header
3) The rest resource method is then accessed if valid credentials are present
But before step 3, I want to somehow pass on the loaded User object to the actual Resource method itself so I can further apply some logic to restrict what the user can see based on the permissions that I have loaded??? Is this possible? I think I have seen some code somewhere that checks for User Roles before a method is accessed using Spring and REST but if anyone has any links or ideas that would be excellent.
Please help if you can. thank you so much.
I solved this by using a request-scoped proxy which was constructed by a bean factory.
This allows you to simply inject your currently authenticated user into any spring managed bean, and in my case my Jersey Resources fell into that category. I injected my user into the tier below the resources, but it's all the same.
Someone else elegantly blogged the full solution here.