Put ResponseExceptionMapper on keycloak admin client - keycloak

I use the keycloak admin client :
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-keycloak-admin-client</artifactId>
<version>2.15.0.CR1</version>
</dependency>
I have the following code :
try {
realm.users().get(userId.toString()).resetPassword(credentialRepresentation);
} catch (NotFoundException notFoundException) {
log.debug(String.format("No user found for id %s", userId.toString()), notFoundException);
throw new MyException();
} catch (BadRequestException e) {
// Need message detail from keycloak response
}
When i catch the exception the javax.ws.rs.BadRequestException is wrapped inside a org.jboss.resteasy.client.exception.ResteasyBadRequestException.
Unfortunatly i need to access javax.ws.rs.BadRequestException to get the return body.
How can i prevent the keycloak admin client to wrap the original exception ?
Is it possible to add a ResponseExceptionMapper for this client ?

Related

How to handle UndeliverableException error thrown via blockingFirst() in Micronaut?

Below is a snippet from my micronaut web service:
try {
val result = hClient.exchange(GET<String>("$readEndpoint/$token")).blockingFirst()
logger.error("result")
} catch (e: Exception) {
logger.error(e.message)
}
hClient is a reactive http client injected as #Inject val hClient: RxHttpClient
The endpoint is throwing "Connection reset by peer" exception.
Issue I am facing
Even though I have wrapped code in try and catch, An exception io.reactivex.exceptions.UndeliverableException is thrown and not caught.
I basically get two exceptions thrown, one is caught by catch block with message Error occurred reading HTTP response: Connection reset by peer, another one is flowing up to service with message io.reactivex.exceptions.UndeliverableException: The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with. Further reading: https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling | java.nio.channels.ClosedChannelException
Reproducible via below code
Keep timeout too less to receive a timeout error.
micronaut:
http:
client:
read-timeout: 1s
#Controller("/")
class TokenController(
#Client("https://hello123456789.com/dummy") #Inject val hClient: RxHttpClient
) {
#Get("/test")
fun refresh(): String {
try {
val result = hClient.exchange(HttpRequest.GET<String>("/token/1234")).blockingFirst()
println("result")
} catch (e: Exception) {
println(e.message)
}
return ""
}
}
Googling told me that I need to add global onError to rxjava but couldn't find how to do that in Micronaut.
Any help is appreciated.

Grails injected Mail Service bean is null inside a controller

I am trying to use the following Grails Mail plugin: https://grails.org/plugin/mail
I've added the depedency in BuildConfig.groovy:
plugins {
//mail plugin
compile "org.grails.plugins:mail:1.0.7"
}
The I've configured it to use a specific email by adding the following code in Config.groovy:
grails {
mail {
host = "smtp.gmail.com"
port = 465
username = "-my email-"
password = "-my password-"
props = ["mail.smtp.auth":"true",
"mail.smtp.socketFactory.port":"465",
"mail.smtp.socketFactory.class":"javax.net.ssl.SSLSocketFactory",
"mail.smtp.socketFactory.fallback":"false"]
from = "no-reply#kunega.com"
}
}
I have a controller where I declare the mailService so it should be injectd as a bean:
#Secured("permitAll")
class RegisterController {
def mailService
def springSecurityService
#Transactional
def registerAccount(UserCommand userCommand) {
def model
if (springSecurityService.isLoggedIn()) {
model = [success: false, message: 'Log out to register a new account.']
response.status = 400
} else if (userCommand.validate()) {
User u = userCommand.createUser()
u.save(flush: true);
Role role = Role.findByAuthority("ROLE_USER")
UserRole.create u, role, true
def link = createLink(controller: 'register', action: 'activateAccount', params: [code: u.confirmCode])
mailService.sendMail {
async true
to 'kunega#mailinator.com'
html "Activate your account on Kunega"
}
model = [success: true, message: 'An activation link has been sent to your email.']
response.status = 201
} else {
model = [success: false, errors: userCommand.getErrors()]
response.status = 400
}
render model as JSON
}
}
I am trying to use the sendMail method it in the registerAccount method of the controller. However I get an error, which basically says that the mailService object is null. Here is the error message:
errors.GrailsExceptionResolver NullPointerException occurred when processing request: [POST] /Kunega/register/createAccount
Cannot invoke method $() on null object. Stacktrace follows:
java.lang.NullPointerException: Cannot invoke method $() on null object
at com.kunega.RegisterController$_$tt__registerAccount_closure2.doCall(RegisterController.groovy:32)
at grails.plugin.mail.MailService.sendMail(MailService.groovy:53)
at grails.plugin.mail.MailService.sendMail(MailService.groovy:59)
at com.kunega.RegisterController.$tt__registerAccount(RegisterController.groovy:29)
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:198)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.java:53)
at grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter.doFilter(RequestHolderAuthenticationFilter.java:49)
at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:82)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
And there is another strange thing that I should mention. I'm using IntelliJ Ultimate Edition, and here is a curios thing:
If you notice inside the highlighted area with red, the IDE is showing that it can't recognize the arguments inside the closure that is passed to sendEmail.
I've never used this plugin before, so I just followed the steps in the docs, but apparently something is wrong. Thank you for your help.
In your code you have:
html "Activate your account on Kunega"
which I suppose should be either:
html "Activate your account on Kunega"
or
html "Activate your account on Kunega"
otherwise you call a method html with params "Activate your account on Kunega".

LDAP Authentication not working with Online LDAP Test Server

I am using the below configuration to connect to Online LDAP Test Server
<className>com.worklight.core.auth.ext.LdapLoginModule</className>
<parameter name="ldapProviderUrl" value="ldap://forumsys.com:389"/>
<parameter name="ldapTimeoutMs" value="2000"/>
<parameter name="ldapSecurityAuthentication" value="simple"/>
<parameter name="validationType" value="searchPattern"/>
<parameter name="ldapSecurityPrincipalPattern" value="uid={username},ou=mathematicians,dc=example,dc=com"/>
<parameter name="ldapSearchFilterPattern" value="(uid={username})"/>
<parameter name="ldapSearchBase" value="dc=example,dc=com"/>
But i am getting
"FWLSE4014W: LdapLoginModule authentication failed. Reason 'javax.naming.CommunicationException: forumsys.com:389 [Root exception is java.net.SocketTimeoutException: connect timed out]" error.
Is there anything wrong with the settings ?
that server is pretty old and the LDAP service is no longer active
This exception is not unique to MobileFirst and so I remove this information from the question.
See here: http://www-01.ibm.com/support/docview.wss?uid=swg21599197.
I suggest that you will follow the same solution steps, which are to verify that you are attempting to correctly connect to your LDAP server.
Recommended but optional: Download a third-party tool (such as the ldapsearch tool) that can verify your server(s) are able to communicate with the LDAP server independent of the Portal ConfigEngine configuration task. Run the tool directly from the Portal server (and Deployment Manager if clustered) to verify all servers can communicate with the LDAP server.
In this particular use case, a network firewall was configured to block all traffic to the LDAP server except from IP addresses that were explicitly whitelisted / permitted to connect. The primary Portal server had been configured in the network firewall to communicate with the LDAP server, but the Deployment Manager had not been configured. Adding the Deployment Manager IP address to the firewall rules allowed the configuration task to complete successfully.
I recently used ForumSys LDAP Test server mentioned using KeyCloak successfully:
You can find all the configuration here.
If you are looking for an easily configurable dockerized test LDAP authentication server.
try
https://hub.docker.com/r/upekshejay/simple-ldap-test-server
I used ForumSys LDAP Test Server
, here is fully tested sample used to check if a user is already inside an active directory.
public class ActiveDirectoryManagerTwo {
final static String domainTree = "dc=example,dc=com";
public static void main(String[] args) {
System.out.println(isInsideActiveDirectory("tesla"));
}
public static String isInsideActiveDirectory(String userName) {
String isFound = "NO";
String rootDN = "cn=read-only-admin,dc=example,dc=com";
String rootPWD = "password";
Hashtable<String, String> environment = new Hashtable<String, String>();
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
environment.put(Context.PROVIDER_URL, "ldap://ldap.forumsys.com :389");
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
environment.put(Context.SECURITY_PRINCIPAL, rootDN);
environment.put(Context.SECURITY_CREDENTIALS, rootPWD);
DirContext dirContext = null;
NamingEnumeration<?> results = null;
try {
System.out.println("inside try");
dirContext = new InitialDirContext(environment);
SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String filter = "(&(uid=" + userName + "))";
results = dirContext.search(domainTree, filter, controls);
if (results.hasMore()) {
isFound = "YES";
} else {
}
} catch (NamingException e) {
System.out.println("inside catch");
e.printStackTrace();
} finally {
if (results != null) {
try {
results.close();
} catch (Exception e) {
}
}
if (dirContext != null) {
try {
dirContext.close();
} catch (Exception e) {
}
}
}
return isFound;
}
}

Creating new user with Smack on ejabberd throws XMPP Exception: forbidden(403)

Hi I am working on ejabberd and I am quite new to this technology.
I am trying to add a user on my ejabberd server using this code:
try {
conf.setSASLAuthenticationEnabled(true);
connection.connect();
Roster.setDefaultSubscriptionMode(Roster.SubscriptionMode.manual);
Log.i("XMPPClient", "Connected to "
+connection.getHost());
createUser("tester","testerpass");
}
} catch (XMPPException e1) {
Log.e("XMPPClient", e1.toString());
xmppClient.setConnection(null);
}
public void createUser(String user, String pass) {
try {
//Admin login
connection.login(user, pass);
} catch (XMPPException e) {
e.printStackTrace();
}
Log.i("connection.isAuthenticated() : ",""+connection.isAuthenticated() );
if (connection.isAuthenticated()) {
AccountManager manager = connection.getAccountManager();
try {
manager.createAccount(user, pass);
} catch (XMPPException e) {
Log.w("[create_user] Cannot create new user: XMPP Exception.", "0");
e.printStackTrace();
} catch (IllegalStateException e) {
Log.w("[create_user] Cannot create new user: not logged in.", "0");
e.printStackTrace();
}
}
}
Its connecting to server and admin login is perfectly But during creating new account
it gives forbidden 403 error that is :
06-15 20:01:40.092: I/XMPPClient(1300):Connected to 68.178.255.136
06-15 20:01:41.952: I/connection.isAuthenticated() :(1300): true
06-15 20:01:42.562: W/[create_user] Cannot create new user: XMPP Exception.(1300): 0
06-15 20:01:42.562: W/System.err(1300): forbidden(403)
06-15 20:01:42.562: W/System.err(1300): at org.jivesoftware.smack.AccountManager.createAccount(AccountManager.java:246)
I would be very thankful if somebody can suggest a workarround for this .
Goto C:\Program Files (x86)\ejabberd-2.1.8\conf (in my case) folder & open ejabberd.cfg file using Notepad++ (it is easy to edit using it).
In the file do the following changes:
%% Put this in the section ACCESS RULES
{access, register_from, [{allow, admin}]}.
%% Change mod_register so it contains the new access rule:
{mod_register, [
{access_from, register_from},
...
] ...
I want to update the answer to reflect the change in Asmack library version 4.0 onward.
Connection.getAccountManager() is now AccountManager.getInstance(XMPPConnection)
AccountManager accountManager=AccountManager.getInstance(connection);
try {
accountManager.createAccount("username", "password");
} catch (XMPPException e1) {
Log.d(e1.getMessage(), e1);
}
In my case, i need to edit the file EJABERD_HOME/conf/ejabberd.yml, on mod_register change parameters to:
ip_access : all
access_from : all
access: register
To allow users register from another host
For yaml configuration as follows.
access_rules:
local:
allow: all
configure:
allow: all
trusted_network:
allow: all
register:
allow: all
.......
modules:
mod_register:
ip_access: trusted_network
access: register
access_from: all
Note: This is allow all configuration. Make strict configuration as required.

Apache Abdera Client giving No credentials available for NTLM <any realm>#proxy.tcs.com:8080

I have seen many forum posts for this and tried several suggestions but still I am not able to solve this. The code works good at my home system, but behind the organization firewall it gives a exception message :
No credentials available for NTLM #proxy.tcs.com:8080
Here is the method which I am using
private static void UseAbdera() throws IOException
{
try
{
Abdera abdera = new Abdera();
AbderaClient client = new AbderaClient(abdera);
client.setProxy("OrgProxyHost", 8080);
NTLMAuthenticatorClass authenticator = new NTLMAuthenticatorClass("username", "password");
Authenticator.setDefault(authenticator);
NTCredentials ntcr = new NTCredentials("username", "password", "greenhouse.lotus.com", "India.TCS.com");
client.addCredentials("https://greenhouse.lotus.com", null, null, ntcr);
ClientResponse resp = client.get("https://greenhouse.lotus.com/forums/atom/service");
org.apache.abdera.model.Document<org.apache.abdera.model.Service> service_doc = resp.getDocument();
service_doc.writeTo(System.out);
System.out.println("\n");
org.apache.abdera.model.Service service = service_doc.getRoot();
org.apache.abdera.model.Collection collection = service.getCollection("Forums Feed Collection", "My Topics");
String coll_uri = collection.getResolvedHref().toASCIIString();
org.apache.abdera.model.Entry entry = abdera.newEntry();
entry.setTitle("TEST REPLY !");
// Mark private
resp = client.post(coll_uri, entry);
switch (resp.getType())
{
case SUCCESS:
String location = resp.getLocation().toASCIIString();
System.out.println("New entry created at: " + location);
break;
default:
System.out.println("Error: " + resp.getStatusText());
}
} catch (URISyntaxException ex)
{
Logger.getLogger(IBMConnectionMessages_ForumPractice.class.getName()).log(Level.SEVERE, null, ex);
}
}
This is the exception log I get
org.apache.commons.httpclient.auth.AuthChallengeProcessor selectAuthScheme
INFO: ntlm authentication scheme selected
Jul 6, 2012 10:42:03 AM org.apache.commons.httpclient.HttpMethodDirector processProxyAuthChallenge
INFO: No credentials available for NTLM #orgProxyHost:8080
Exception in thread "main" java.lang.IllegalStateException
at org.apache.abdera.protocol.client.CommonsResponse.(CommonsResponse.java:44)
at org.apache.abdera.protocol.client.AbderaClient.execute(AbderaClient.java:692)
at org.apache.abdera.protocol.client.AbderaClient.get(AbderaClient.java:216)
at org.apache.abdera.protocol.client.AbderaClient.get(AbderaClient.java:404)
at IBMConnectionMessages_ForumPractice.UseAbdera(IBMConnectionMessages_ForumPractice.java:231)
at IBMConnectionMessages_ForumPractice.main(IBMConnectionMessages_ForumPractice.java:45)
Please help, I have spent half a day on it.
your proxy may need ntlm authentication, so provide your proxy authentication details as NTCredentials while setting proxy credentials.