Keycloak Federated Users - Trigger Password Reset Email in Custom SPI - keycloak

We implemented a keycloak SPI to perform lookups/updates on an external user database.
One of the features we wanted to implement is to trigger an email when users reach a certain number of login attempts. This is something we did in pre-keycloak version of our application and attempting to implement this feature.
The guidance is to use the execute-actions-email admin REST end point by supplying the "UPDATE_PASSWORD" required action along with other inputs. But I consistently get a 403 response.
I was looking around if in the custom SPI there is a way to use the Keycloak Java API instead. I found an implementation of the executeActionsEmail method in UserResource. But this needs some additional initializations (mostly admin privileges I think). I'm stuck here as well.
I'm looking for any working example(s) that would help me understand how to implement this use case. Postman, Java API any thing would be highly appreciated.
Thank you,

This is the final solution:
private boolean triggerExecuteActionsEmailAdminClient(RealmModel realm, UserModel user) {
boolean executed = false;
try {
KeycloakContext context = keycloakSession.getContext();
UriInfo backendUriInfo = context.getUri(UrlType.BACKEND);
String backendBaseUri = backendUriInfo.getBaseUri().toString();
log.info(String.format("backendBaseUri: %s", backendBaseUri));
Keycloak keycloak = KeycloakBuilder.builder().serverUrl(backendBaseUri).realm("master")
.clientId("admin-cli").grantType("password").username("admin").password("******")
.resteasyClient(new ResteasyClientBuilder().connectionPoolSize(10).build()).build();
String realmName = realm.getName();
String userId = user.getId();
keycloak.realm(realmName).users().get(userId).executeActionsEmail(Arrays.asList("UPDATE_PASSWORD"));
executed = true;
} catch (Exception e) {
e.printStackTrace();
}
return executed;
}
standalone.xml in jboss:domain:ee subsystem
<global-modules>
<module name="org.keycloak.keycloak-core"/>
<module name="org.keycloak.keycloak-admin-client"/>
</global-modules>
In lieu of the above, I added the dependencies in the jboss deployment descriptor of the installed custom SPI jar file
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.springframework.security" />
<module name="com.oracledatabase.oracle" />
<module name="org.keycloak.keycloak-core"/>
<module name="org.keycloak.keycloak-server-spi"/>
<module name="org.keycloak.keycloak-server-spi-private"/>
<module name="org.keycloak.keycloak-services"/>
<module name="org.keycloak.keycloak-saml-core-public"/>
<module name="org.keycloak.keycloak-admin-client"/>
<module name="org.jboss.logging"/>
</dependencies>
</deployment>
Installing the keycloak-admin-client module, make sure keycloak-admin-client-14.0.0.jar is available in /tmp
sudo $KEYCLOAK_HOME/bin/jboss-cli.sh --command="module add --name=org.keycloak.keycloak-admin-client --resources=/tmp/keycloak-admin-client-14.0.0.jar --dependencies=org.keycloak.keycloak-core,org.keycloak.keycloak-common,org.apache.httpcomponents,javax.ws.rs.api,org.jboss.resteasy.resteasy-jaxrs"

Related

Datasource configuration in wildfly 10

I am trying to configure a PostgreSQL datasource in Wildfly 10 Application Server on Mac OS. I am doing what the instructions prescribe. I have created an order:
/wildfly-10.1.0.Final/modules/system/layers/base/org/postgresql/main.
In this order I have put the JDBC driver:
postgresql-9.3-1104.jdbc4.jar
and I have created a module.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.3" name="org.postgresql“>
<resources>
<resource-root path="postgresql-9.3-1104.jdbc4.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
</dependencies>
</module>
In the standalone.xml file I have created the datasource under datasources:
<datasource jndi-name="java:jboss/datasources/PostgresDS" pool-name="PostgresDS" enabled="true"
use-java-context="true">
<connection-url>jdbc:postgresql://localhost:5432/testdb</connection-url>
<driver>postgresql</driver>
<security>
<user-name>user</user-name>
<password>password</password>
</security>
<validation>
<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLValidConnectionChecker"></valid-connection-checker>
<exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLExceptionSorter"></exception-sorter>
</validation>
</datasource>
and drivers as:
<drivers>
<driver name="postgresql" module="org.postgresql">
<datasource-class>org.postgresql.Driver</datasource-class>
<xa-datasource-class>org.postgresql.xa.PGXADataSource</xa-datasource-class>
</driver>
</drivers>
However it is impossible the datasource is not installed and when I start the server I get the message (error):
ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread) WFLYCTL0013: Operation ("add") failed - address: ([
("subsystem" => "datasources"),
("data-source" => "PostgresDS")
]) - failure description: {
"WFLYCTL0412: Required services that are not installed:" => ["jboss.jdbc-driver.postgresql"],
"WFLYCTL0180: Services with missing/unavailable dependencies" => [
"org.wildfly.data-source.PostgresDS is missing [jboss.jdbc-driver.postgresql]",
"jboss.driver-demander.java:jboss/datasources/PostgresDS is missing [jboss.jdbc-driver.postgresql]"
]
}
[org.jboss.as.controller.management-operation] (Controller Boot Thread) WFLYCTL0013: Operation ("add") failed - address: ([
("subsystem" => "datasources"),
("data-source" => "PostgresDS")
]) - failure description: {
"WFLYCTL0412: Required services that are not installed:" => [
"jboss.jdbc-driver.postgresql",
"jboss.jdbc-driver.postgresql"
],
"WFLYCTL0180: Services with missing/unavailable dependencies" => [
"org.wildfly.data-source.PostgresDS is missing [jboss.jdbc-driver.postgresql]",
"jboss.driver-demander.java:jboss/datasources/PostgresDS is missing [jboss.jdbc-driver.postgresql]",
"org.wildfly.data-source.PostgresDS is missing [jboss.jdbc-driver.postgresql]"
]
}
It seems, that wildfly maybe does not find the module. Any ideas what causes this problem? Is anything wrong in my configuration?
I'd like to recommend a change to your process. While you certainly can do this by hand, if you script this you can do it again with repeatability.
This is dependent on the jboss-cli.sh. I have a script that looks like:
embed-server --std-out=echo --server-config=standalone.xml
batch
module add --name=org.postgres --resources=/tmp/postgresql-42.0.0.jar --dependencies=javax.api,javax.transaction.api
/subsystem=datasources/jdbc-driver=postgres:add(driver-name="postgres",driver-module-name="org.postgres",driver-class-name=org.postgresql.Driver)
/subsystem=datasources/data-source=myDataSource/:add(connection-url=jdbc:postgresql://localhost:5432/thedatabasename,driver-name=postgres,jndi-name=java:/jdbc/myDataSource,initial-pool-size=4,max-pool-size=64,min-pool-size=4,password=theDatabasePassword,user-name=theDatabaseUsername)
run-batch
This is run with:
bin/jboss-cli.sh --file=/path/to/file/wildflyconf.cli
The script starts by using the "embed-server" command so that your Wildfly instance does not need to be running. Then it starts a batch of commands to run as one unit.
The important part is that we create the module via the command line. You will have to put the PostgreSQL jar somewhere but other than that the script takes care of creating all of the needed files under "modules".
Next, we add the JDBC driver and then we create a Datasource based on the driver.
The advantage of a script is that you can check this into your source code control system and anyone can run it. It reduces the possibility of a typo and you don't need to manually create and modify files.
Just a thought. Having a repeatable process that your development team can use is always a useful thing.
You are defining your Driver class as a Datasource class :
<datasource-class>org.postgresql.Driver</datasource-class>
please use the correct element:
<driver-class>org.postgresql.Driver</driver-class>
just like #stdunbar showed you in his CLI command :
/subsystem=datasources/jdbc-driver=postgres:add(driver-name="postgres",driver-module-name="org.postgres",driver-class-name=org.postgresql.Driver)
in your file module.xml in the 2nd line change
<module xmlns="urn:jboss:module:1.3" name="org.postgresql“>
to
<module xmlns="urn:jboss:module:1.3" name="org.postgresql">
the ' " ' may be the problem in your module.xml
Set the following system properties in standalone.xml and it should work fine:
-Dorg.kie.server.persistence.dialect=org.hibernate.dialect.PostgreSQLDialect
-Dorg.kie.server.persistence.ds=java:jboss/datasources/yourDataSource
<system-properties>
<property name="org.kie.server.persistence.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="org.kie.server.persistence.ds" value="java:jboss/datasources/ExampleDS"/>
</system-properties>
I just faced this issue with Wildfly-20.0.1.Final. I resolved it by adding the Postgres module to /Wildfly-20.0.1.Final/modules/org/postgresql/main
So, the solution to this issue is to move the module from
/wildfly-10.1.0.Final/modules/system/layers/base/org/postgresql/main
to
/wildfly-10.1.0.Final/modules/org/postgresql/main

JBoss logs Postgres driver is "non-JDBC-compliant"

I wired my JBoss server into a new Postgres database.
In standalone.xml:
<driver name="postgresql" module="com.postgresql.pgjdbc">
<driver-class>org.postgresql.Driver</driver-class>
</driver>
In module.xml:
<module xmlns="urn:jboss:module:1.1" name="com.postgresql.pgjdbc">
<resources>
<resource-root path="postgresql-9.3-1102.jdbc41.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
</dependencies>
</module>
When starting JBoss, I get the following log entry:
10:49:57,206 INFO [org.jboss.as.connector.subsystems.datasources] (ServerService Thread Pool -- 25) JBAS010404: Deploying non-JDBC-compliant driver class org.postgresql.Driver (version 9.3)
The driver does seem to connect and work. What are the effects of this non-compliance?
According this JBoss forum entry none: Why is my JDBC4-compliant driver loaded as "non-JDBC-compliant"?
Because org.postgresql.Driver#jdbcCompliant() returns false. So you
can ignore that for now, and I'm sure that the PostgreSQL JDBC people
would like code contributions
And source code:
/**
* Report whether the driver is a genuine JDBC compliant driver. A
* driver may only report "true" here if it passes the JDBC compliance
* tests, otherwise it is required to return false. JDBC compliance
* requires full support for the JDBC API and full support for SQL 92
* Entry Level.
*
* <p>For PostgreSQL, this is not yet possible, as we are not SQL92
* compliant (yet).
*/
public boolean jdbcCompliant()
{
return false;
}
https://github.com/pgjdbc/pgjdbc/blob/REL9_3_1102/org/postgresql/Driver.java.in
This is part of the TODO List http://jdbc.postgresql.org/development/todo.html#Compliance

Wildfly - Proxy Configuration

I just need to configure Wildfly 8 to use an external HTTP Proxy in order to connect to the Internet; can you tell me where and how to specify proxy address and port?
I'm running Wildfly as a service on Windows 7.
Thank you very much for your help!
I did it by adding
set "JAVA_OPTS=%JAVA_OPTS% -Dhttp.proxyHost=MY_PROXY_HOST -Dhttp.proxyPort=MY_PROXY_PORT -Dhttp.proxyUser=MY_LOGIN -Dhttp.proxyPassword=MY_PASSWORD"
into file bin/standalone.conf.bat (I'm using wildfly in the standalone mode)
In other words, Wildfly uses system (JVM) proxy settings well.
We had to go through a few more steps using Wildfly 10:
Overwrite the resteasy-client module in the wildfly layers so that it does not register itself as the default JAX-rs client builder. This is required because jboss will scan its own modules before the ones in our entreprise archive. We added an exclusion in the module.xml:
```
<resource-root path="resteasy-client-3.0.19.Final.jar">
<filter>
<exclude-set>
<path name="META-INF/services"/>
</exclude-set>
</filter>
</resource-root>
```
Implements your own ResteasyClientBuilder to make it use its URLConnection engine. We found out that the default engine (apache http commons) did not honor our http.proxyHost system properties, whereas the java URLConnection engine did.
```
public class ProxifiedClientBuilder extends ResteasyClientBuilder {
public ProxifiedClientBuilder() {
super();
URLConnectionEngine urlConnectionEngine = new URLConnectionEngine();
httpEngine(urlConnectionEngine);
}
}
```
Register your ClientBuilder as the default provider. You can do that in a META-INF/services file or using a system property:
```
<system-properties>
<property name="javax.ws.rs.client.ClientBuilder" value="be.buyway.util.ProxifiedClientBuilder"/>
</system-properties>
```
Hope this helps someone else.

How to add the description of job in spring batch admin user interface?

Is there any way to add the description of job at the user interface of spring batch admin?
Although, I tried to added the description of the job, spring batch admin cannot support it.
I would like to know that whether spring batch admin does not support it or not.
I know i'm late to the party but I figured it out and it works flawlessly for me. All you have to do is :
Add a messages.properties file in your classpath (under
src/main/resources).
Add yourJobName.description=Your description goes here in that file.
Override manager-context.xml for SBA by creating a file on path src/main/resources/META-INF/spring/batch/servlet/override/manager-context.xml
The content of the above created file should be :
`
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- Override messageSource bean in order to provide custom text content -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="messages" />
</bean>
</beans>
`
That's it. Your custom description shows up in SBA. Hope this helps someone who's looking for it.
There isn't the ability out of the box to display the job's description. That is only contained in the XML and the data seen in the UI comes from the JobRepository. You'd have to extend the UI to add that functionality.

GWT: how to write client side logs into a log file in GWT

HI guys i am facing a big problem to write logs in a file in GWT.
i ahd gone through all the posts over internet but i didn't find any valuable information
there.
What i did ...
added remote logging servlet in web.xml file
inherited the logging module in my .gwt.xml file.
But my question is here now suppose i have written one log in my Entry Point class.
like ....
//Main class to start the appliation.....
public void onModuleLoad() {
Logger logger=Logger.getLogger(SYTMain.class.getName());
logger.info("Test Log in Module File");
}
and now i want to write this client side log into a test.log file .
How i can achieve this???/
Please if anyone knows the answer then plz provide me the complete solution, i don't want example on a fly. if you really know then only plz tell me don't give the answer which is already available in net.....
mY delivery date is very near so plz update on same ASAP, i'll be very thankful to you.
In your module file add the following:
<inherits name='com.google.gwt.logging.Logging'/>
<set-property name="gwt.logging.enabled" value="TRUE"/>
<!-- Set logging level to INFO -->
<set-property name="gwt.logging.logLevel" value="INFO"/>
<set-property name="gwt.logging.simpleRemoteHandler" value="ENABLED" />
<!-- Add compiler.stackMode to get a readable stacktrace from JavaScript
It generates a set of files in WEB-INF/deploy; those files need to
be placed on the server
-->
<set-property name="compiler.stackMode" value="emulated" />
In your web.xml add the following:
<servlet>
<servlet-name>remoteLoggingService</servlet-name>
<servlet-class>com.google.gwt.logging.server.RemoteLoggingServiceImpl</servlet-class>
</servlet>
<!-- Servlet Mapping -->
<servlet-mapping>
<servlet-name>remoteLoggingService</servlet-name>
<url-pattern>/<your module name>/remote_logging</url-pattern>
</servlet-mapping>
Replace <your module name> with as it says your module name.
To log simply use the code as your mentions. Use the import from java.util.logging.
On the client side, GWT compiles to Javascript, and Javascript cannot in general write files to the client's filesystem. (It should be obvious why this could be a bad idea). See for example this discussion.
If what you need is logs to use for debugging, one obvious solution is to have the logger append to a text area on the page. You can always copy and past manually into another file. Or, if you want to debug remotely, you could have the logger write to the server.
Just create a RPC service to log it into the server-side.
Use the servlet-side threadlocal to get info about the client: ThreadLocal to store ServletRequest and Response in servlet: what for?.