send http rest request from keycloak X user storage spi to an external api - keycloak

we just started using keycloak x quarkus distribution, and we have made a user storage and user federation spi.
they problem we are facing now is that we are unable to configure our spi in keycloak.properties to set up rest client to send request to an external quarkus api.
before moving to keycloak x we used to use unirest to send http rest requests, but since we moved to the quarkus distribution we started to use quarkus-rest-client dependency (which we use in all of our quarkus applications)
when we startup the keycloak x locally we get the following log
Unrecognized configuration key "quarkus.rest-client."path-to-rest-client-class".url" was provided; it will be ignored; verify that the dependency extension for this configuration is set or that you did not make a typo
which indicate to that keycloak x is unable to use the following dependency:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest-client</artifactId>
</dependency>
and unable to convert the following property in keycloak.properties quarkus.rest-client."path-to-rest-client-class".url to a property in keycloak behind the scene.
we have look at the following Keycloak.X Server Configuration which explain in details about the rules we should follow in order to write configurations in keycloak.properties, and its says that keycloak should have a custom config property for each quarkus property unless it was considered an advanced usage and not supported configuration
so is there an equivalent config property for that? and what is the best way to send a http request from quarkus based user storage spi to an external api?

Related

Why is quarkus.oidc.credentials.secret being ignored?

I have a SPA (Vue.js) that communicates via REST with a Quarkus Resource API .
I am using my own Keycloak for Authentication/Authorization.
In Keycloak I have two clients in my realm:
Client ID: frontend-client
Access Type: public
Standard Flow enabled
Client ID: backend-client
Access Type: bearer-only
Secret: mySecret
My application.properties for my Quarkus API:
quarkus.oidc.auth-server-url=https://localhost:8082/auth/realms/myrealm
#quarkus.oidc.client-id=backend-service
#quarkus.oidc.credentials.secret=mySecret
My SPA uses the Standard Flow to authenticate with Keycloak and then redirects to my app ✅
Then I can make requests to my API and everything works despite quarkus.oidc.client-id and quarkus.oidc.credentials.secret being commented out ! Why is that? It also works when those lines are not commented out but with false values. 😳
Why is Quarkus ignoring those lines, and, more importantly, why does it work?
UPDATE
Adding the dependency
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-keycloak-authorization</artifactId>
</dependency>
Allows me to add this to application.properties:
quarkus.keycloak.policy-enforcer.enable=true
It now leads to this error:
{"error":"invalid_client","error_description":"Bearer-only not allowed"}
But at least now the secret is not being ignored, and providing a wrong secret leads to the correct error.
Follow-up question: Why is bearer-only not allowed?
I'm guessing that because your Quarkus application use a bearer only client, it will only check the authenticity of the bearer token using the signature.
Since it will not make any call to Keycloak for additional verifications, it will not use the client id and client secret in your properties.
You need to change the type of the client to confidential if you want quarkus to use that.
By the way, in the quarkus quickstart for protecting service applications : the keycloak client use a confidential client, and bearer only is set to false : https://github.com/quarkusio/quarkus-quickstarts/blob/main/security-openid-connect-quickstart/config/quarkus-realm.json#L395

Keycloak server embedded in a Spring Boot application with custom User Storage SPI

I have managed to set up a Keycloak server embedded in a Spring Boot Application successfully, following this tutorial:
Keycloak Embedded in a Spring Boot Application
in order to avoid setting it up manually.
Since I am dealing with an old implementation that already has it's own DB, I decided to use Keycloak's User Storage SPI to connect to an external postgresql DB and use this for authentication instead of Keycloak DB.
To do this, I followed the tutorial on Keycloak documentation, but it envolves a standalone Keycloak server, creating a .jar with the custom provider and injecting it to <pathToKeycloak>/standalone/deployments/.
I have created an implementation that works with a standalone Keycloak server, but now I want to include it to the embedded one. Is it possible to use a Keycloak server Embedded in a Spring Boot Application and also have an embedded custom User Storage Provider, to avoid setting up manually?
If you have already implemented the provider and the provider factory, you only need to declare the provider factory class in the resources/META-INF/services/org.keycloak.storage.UserStorageProviderFactory file.
Then you can log in to the administration console and enable user storage provider on the User Federation page.

Retrieve logged user information from cloud foundry web application

We developed a web application using SAP Web-IDE Full Stack; we need to retrieve the details of the user logged into application (as defined in SAP Cloud Platform Identity Authentication Administration), for example display name and assigned groups.
We tried the userapi/currentUser API, but it seems to work only on NEO environment, for this reason is working fine while debugging in Web-IDE, but we get a 404 error when deploying the app on Cloud Foundry.
Do we need to add a new destination to make userapi work also on CF? Or is there some kind of similar solution available on Cloud Foundry?
I highly suggest using the SAP S/4HANA Cloud SDK for such tasks. It is an SDK developed to make building applications for SAP Cloud Platform easy, by providing easy to use mechanisms for all the Cloud Platform mechanisms.
Regarding your task at hand, there is a UserAccessor class that you can use like this:
final Optional<User> user = UserAccessor.getCurrentUser();
This works on Neo as well as on Cloud Foundry, i.e. there is a single interface for both platforms, which allows you to develop your app in a platform agnostic way.
If this sounds like it could solve your problem, I recommend checking out this blog post series to get started.
Alternatively, you can also simply add the following dependency to your project to start testing the SDK:
<dependency>
<groupId>com.sap.cloud.s4hana.cloudplatform</groupId>
<artifactId>scp-neo</artifactId>
<version>2.7.0</version>
</dependency>
For Cloud Foundry use scp-cf instead of scp-neo.
Hope this helps!
P.S.: To answer your question also on a technical level, Cloud Foundry uses so-called JWTs for authentication and authorization. You can check whether a JWT is present by looking at the Authorization header of the request. The JWT should hold the information you're looking for.
In SAP Cloud Foundry if you develop a MTA using XSUAA service to manage User Authentication and Admistration, defined for example in the mta.yaml,
...
resources:
- name: uaa_myapp
parameters:
path: ./xs-security.json
service-plan: application
service: xsuaa
type: org.cloudfoundry.managed-service
...
you can use the UAA API published from XSUAA service self to manage user authentication and authorization (e.g.: retrieve user info, groups assigned, password management etc..). also in the case the application is federated with another IDP.
To consume this API for example to retrieve user info you need to:
Determine the XSUAA endpoint bound to your app (SCP Cockpit > XSUAA service detail > take the value url)
Create a destination (xsuaa_api_destination) of type OAuth2TokenExchange bound to your app with url url took before, and fill OAuth2 authentication parameters with the data contained in XSUAA service detail (step 1).
From your app execute the call xsuaa_api_destination/userinfo, for example using an ajax if you are using JS.
You can find other info in Account and Authentication Service of the Cloud Foundry Environment SAP doc.

Add claims to Wso2 service provider through AdminServices

So i am trying to add claims to a service provider in Wso2. I have managed to create an IdentityApplication and connect it with some SSO configuration. The only problem is adding Claims to that SSO because i use those after the SSO login.
So what i have tried so far:
I have added an SSO configuration using the addRPServiceProvider soap function from the IdentitySAMLSSOConfigService
I have created a service provider using createApplication soap function from the IdentityApplicationManagementService and connected it to the SSO configuration i added earlier
At this point my external application connects correctly with Wso2 and do the SSO. The only thing i need is to return additional claim info with the SSO response.
I am trying to do that using the claimConfig part of the createApplication function parameters but i cant seem to make it right.
Is there somewhere some more info about how to set this up through the AdminServices? ( the official docs are not really helping
)
Please refer this documentation for more information on using the API. You can't add the claimConfig during the createApplication call as it only allows you to set the applicationName and description. Set the claimConfig during updateApplication method. The document has a sample request in Claim configuration level parameters section.

WSO2 ESB-4.8.1 connecting to WSO2-5.0.0 IS and UserInformationRecoveryService?wsdl

I am trying to connect WSO2 Identity Server to the WSO2 ESB. I have installed both products to my local computer and have configured them to run simultaneously. WSO2-IS has an offset of 1 and I set hostnameverifier to AllowAll. Given that both are on my local machine, I did not see the need to adjust or set anything in the Keystore. In WSO2-IS I have exposed the admin-wsdl's.
What I am trying to do is create an endpoint wsdl that points to
https://localhost:9444/services/UserInformationRecoveryService?wsdl (which is in the WSO2-IS).
In the admin console, I add the endpoint with the variables
1. The Name is UserInformationRecoveryService
2. The URI is https://localhost:9444/services/UserInformationRecoveryService?wsdl
3. The Service is UserInformationRecoveryService
4. The port is 9444 (which is the offset from 9443)
When I test this service, it says it is valid. When I add it, it disappears and I get the errors:
[2015-01-16 17:59:20,923] ERROR - WSDL11EndpointBuilder Couldn't retrieve endpoint information from the WSDL.
[2015-01-16 17:59:20,924] ERROR - WSDLEndpointFactory Couldn't create endpoint from the given WSDL URI : Couldn't retrieve endpoint information from the WSDL.
org.apache.synapse.SynapseException: Couldn't retrieve endpoint information from the WSDL.
at org.apache.synapse.config.xml.endpoints.utils.WSDL11EndpointBuilder.handleException(WSDL11EndpointBuilder.java:199)
... (I removed many of the other at's)
I also tried adding it as a wsdl proxy, but receive the error
Couldn't create endpoint from the given WSDL URI : Couldn't retrieve endpoint information from the WSDL.
and the errors:
[2015-01-16 18:06:49,890] ERROR - ProxyServiceAdminClient Couldn't create endpoint from the given WSDL URI : Couldn't retrieve endpoint information from the WSDL.
org.wso2.carbon.proxyadmin.stub.ProxyServiceAdminProxyAdminException: Couldn't create endpoint from the given WSDL URI : Couldn't retrieve endpoint information from the WSDL.
at org.wso2.carbon.proxyadmin.ui.client.ProxyServiceAdminClient.addProxy(ProxyServiceAdminClient.java:105)
at org.apache.jsp.proxyservices.template_005fwsdl_002dbased_jsp._jspService(org.apache.jsp.proxyservices.template_005fwsdl_002dbased_jsp:343)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:111)
I am relatively new to the WSO2 suite, and have been unable to find many discussions on these two products working together.
From what I have read, WSO2-IS uses SOAP. The client that we are developing will be using REST. The ESB is to connect the client to WSO2-IS and convert SOAP-TO-REST.
My question is
1. Why do I receive these errors?
2. What is the best practice to connect the two services.
Thank you.
Enable option in carbon.xml and try your wsdl link in a browser and see whether you can access it or not.(All admin services's wsdls are hided) Later try to create proxy.
After more reading, I found that I was using the wrong port name. I was assuming the port was 9444, but having reread the wsdl again, I found that the ports were called
wsdl:port name="UserInformationRecoveryServiceHttpsSoap11Endpoint"
wsdl:port name="UserInformationRecoveryServiceHttpsSoap12Endpoint"
wsdl:port name="UserInformationRecoveryServiceHttpsEndpoint"