Get HTTP Request in JAAS - LoginModule

437 views
Skip to first unread message

tf19

unread,
Jan 30, 2023, 12:51:31 PM1/30/23
to WildFly
Hello, 

I wrote a custom JAAS - LoginModule exactly like this example 
and everything works fine. 

Now I want to get additional information from the HTTP Header to use for authentication purposes.
What is the best way to achieve this? 

Thanks in advance for any advice.

Cameron Rodriguez

unread,
Jan 30, 2023, 1:17:39 PM1/30/23
to tf19, WildFly
Hey,

The best method would be to use a ServerAuthModule from Jakarta Authentication (JASPI). You can find an example here (note that some classes, like ServerAuthModule may need to be updated to use jakarta.* packages): https://darranl.blogspot.com/2018/10/using-wildfly-elytron-jaspi-with.html


--
You received this message because you are subscribed to the Google Groups "WildFly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wildfly+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/wildfly/b52d94dd-52a9-467b-830f-b0720103e05dn%40googlegroups.com.


--
Cameron Rodriguez (he/him)
Software Engineering Intern
WildFly Elytron

tf19

unread,
Jan 31, 2023, 9:38:29 AM1/31/23
to WildFly
Hello Cameron, 

First of all, thanks for your quick advice!

I am trying to implement a ServerAuthModule and ran in the following problem.

Everytime the ServerAuthModule is called I get a runtime java.lang.ClassCastException that it cannot cast from my class to jakarta.security.auth.message.module.ServerAuthModule. 

Caused by: java.lang.ClassCastException: Cannot cast my.company.authentication.SimpleServerAuthModule to jakarta.security.auth.message.module.ServerAuthModule
    at java.base/java.lang.Class.cast(Class.java:3889)


I implemented the abstract methods from the interface and used the same jakarta.security[..] .jar in the same version(3.0) as the wildfly. 
Additionally I added a zero parameter constructor.

Do you know what could be the problem?
 

Thanks for any help!

Cameron Rodriguez

unread,
Jan 31, 2023, 11:52:51 AM1/31/23
to tf19, WildFly
Hey,

Could you provide a full error log, or the ServerAuthModule implementation class? That would help me to identify what may be causing the issue. In the meantime, I've updated the demo app I linked from yesterday for WildFly 27.0.1 and Jakarta EE, so you should be able to follow it more directly. The changes aren't merged into the repo yet, but for now you can view it here: https://github.com/wildfly-security-incubator/elytron-examples/tree/b9643b54f226ffdf9b58eabd230202655237c7fa/undertow-standalone-jaspi

tf19

unread,
Feb 1, 2023, 6:22:50 AM2/1/23
to WildFly
Hey, 
 
Thanks for your help again, I am really struggling to get this to work properly.

I tried your new ServerAuthModule implementation and got the same error. 

I use Wildfly 27.0.1 and use the same pom.xml to build my ServerAuthModule. The only thing I do different is the configuration, I don't configure programmatically.

I define a module with: 

module add --name=auth --resources=C:\data\wildfly-27.0.1.Final\auth-1.0-jar-with-dependencies.jar

and configure JASPI like: 

 /subsystem=elytron/jaspi-configuration=simple-configuration:add(description="Elytron Test Configuration", server-auth-modules=[{class-name=my.company.security.auth.SimpleServerAuthModule, module=auth, flag=OPTIONAL}])

The error I get:

java.lang.RuntimeException: WFLYELY01057: Failed to create ServerAuthModule [my.company.security.auth.SimpleServerAuthModule] using module 'auth'
    at org.wildfly.ex...@19.0.1.Final//org.wildfly.extension.elytron.JaspiDefinition$2.get(JaspiDefinition.java:162)
    at org.wildfly.ex...@19.0.1.Final//org.wildfly.extension.elytron.JaspiDefinition$2.get(JaspiDefinition.java:153)
    at org.wildfly.security....@3.0.0.Final//org.wildfly.security.auth.jaspi.impl.ElytronServerAuthContext.<init>(ElytronServerAuthContext.java:61)
    at org.wildfly.security....@3.0.0.Final//org.wildfly.security.auth.jaspi.impl.ElytronServerAuthConfig.getAuthContextID(ElytronServerAuthConfig.java:84)
    at org.wildfly.security....@3.0.0.Final//org.wildfly.security.auth.jaspi.impl.WrappingServerAuthConfig.lambda$getAuthContextID$0(WrappingServerAuthConfig.java:63)
    at org.wildfly.security....@3.0.0.Final//org.wildfly.security.auth.jaspi.impl.ThreadLocalCallbackHandler.get(ThreadLocalCallbackHandler.java:56)
    at org.wildfly.security....@3.0.0.Final//org.wildfly.security.auth.jaspi.impl.WrappingServerAuthConfig.getAuthContextID(WrappingServerAuthConfig.java:63)
    at org.wildfly.security.elytron...@3.0.0.Final//org.wildfly.elytron.web.undertow.server.servlet.ServletSecurityContextImpl.authenticate(ServletSecurityContextImpl.java:166)
    at org.wildfly.security.elytron...@3.0.0.Final//org.wildfly.elytron.web.undertow.server.servlet.ServletSecurityContextImpl.authenticate(ServletSecurityContextImpl.java:101)
    at io.undert...@2.3.0.Final//io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:55)
    at io.under...@2.3.0.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.under...@2.3.0.Final//io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:53)
    at io.under...@2.3.0.Final//io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
    at io.undert...@2.3.0.Final//io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
    at io.undert...@2.3.0.Final//io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:59)
    at io.under...@2.3.0.Final//io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
    at org.wildfly.security.elytron...@3.0.0.Final//org.wildfly.elytron.web.undertow.server.servlet.CleanUpHandler.handleRequest(CleanUpHandler.java:38)
    at io.under...@2.3.0.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at org.wildfly.ext...@27.0.1.Final//org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
    at io.under...@2.3.0.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at org.wildfly.ext...@27.0.1.Final//org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
    at io.undert...@2.3.0.Final//io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52)
    at io.under...@2.3.0.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undert...@2.3.0.Final//io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:275)
    at io.undert...@2.3.0.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:134)
    at io.undert...@2.3.0.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:131)
    at io.undert...@2.3.0.Final//io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
    at io.undert...@2.3.0.Final//io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
    at org.wildfly.ext...@27.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1435)
    at org.wildfly.ext...@27.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1435)
    at org.wildfly.ext...@27.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1435)
    at org.wildfly.ext...@27.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1435)
    at org.wildfly.ext...@27.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1435)
    at io.undert...@2.3.0.Final//io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:255)
    at io.undert...@2.3.0.Final//io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:100)
    at io.under...@2.3.0.Final//io.undertow.server.Connectors.executeRootHandler(Connectors.java:391)
    at io.under...@2.3.0.Final//io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:859)
    at org.jbos...@2.4.0.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
    at org.jbos...@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
    at org.jbos...@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
    at org.jbos...@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1348)
    at org.jbo...@3.8.8.Final//org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1282)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.ClassCastException: Cannot cast my.company.security.auth.SimpleServerAuthModule to jakarta.security.auth.message.module.ServerAuthModule
    at java.base/java.lang.Class.cast(Class.java:3605)
    at org.wildfly.ex...@19.0.1.Final//org.wildfly.extension.elytron.JaspiDefinition$2.get(JaspiDefinition.java:160)
    ... 42 more



Do you have any more ideas? 

Thanks in advance!

Cameron Rodriguez

unread,
Feb 1, 2023, 11:35:13 AM2/1/23
to tf19, WildFly
Hey, thanks for the logs. I also tested deploying the module from the quickstart with the CLI, and I was able to add it to a configuration. It's a bit difficult to tell what the issue is since the logs cut themselves off, but I suspect there may be a class conflict[1]. Here's a few ideas that come to mind:
  • Use module remove to remove any modules that packaged an implementation of ServerAuthModule, and then fully shutdown and restart the server, before trying to deploy again.
    • WildFly's static modules[2] are persistent until the server is fully stopped.
  • You could try to add the JBoss module dependencies, although this shouldn't be needed. Use the same steps as above, but use this command instead for deployment:
module add --name=auth --resources=C:\data\wildfly-27.0.1.Final\auth-1.0-jar-with-dependencies.jar --dependencies=jakarta.security.auth.message.api,jakarta.servlet.api
  • If neither works, try enabling more detailed logs[3] for Elytron, which might reveal the issue more clearly:
/subsystem=logging/logger=org.wildfly.security:add(level=DEBUG)
/subsystem=logging/logger=org.wildfly.extension.elytron:add(level=DEBUG)
/subsystem=logging/console-handler=CONSOLE:write-attribute(name=level,value=DEBUG)

Let me know if you have any success. If not, I can try to take a look at the debug logs or a redacted version of the ServerAuthModule implementation.

[1]: https://stackoverflow.com/a/8035915/19546298

tf19

unread,
Feb 8, 2023, 7:47:23 AM2/8/23
to WildFly
Hey,

thank you so much for your support! I got it integrated with adding the JBoss dependencies.

Right now I am a bit stuck with the "workflow" of my custom Login.

I need the ServerAuthModule to get Information out of the HTTP - Request (like Remote - IP-Address or username/password) to invoke my JAAS Login-Module with information resulting of this.
The user should get redirected to the Loginform if the authentication with header informations (username/password, IP-Address) wasn't successful.
The Loginform which shows up in this case should also authenticate against the JAAS-Login-Module.

I invoked the JAAS - Module with request.login(username/password) in the validateRequest - Method in my ServerAuthModule.
And saw in logging that it got called.

Now I am stuck with finding a solution for the next steps:

How can I "redirect" in my secured content after successfully authenticating in the ServerAuthModule?
How can I "redirect" to the Loginform (and proceed with normal authentication) after the authentication with HTTP - Header was not successful?
Is this the correct way to do this?

Thank you!

Diana Krepinska

unread,
Feb 10, 2023, 6:27:55 PM2/10/23
to WildFly
Hello, another possibility you can try is to obtain additional information out of the HTTP request by implementing a custom HTTP mechanism. Here is a blog post https://darranl.blogspot.com/2018/02/wildfly-elytron-implementing-custom.html and an example https://github.com/wildfly/quickstart/tree/main/http-custom-mechanism . Then if the jaas realm authentication is successful you should be able to access your secured content automatically. Note that it is preferable to implement a custom security realm instead of using the jaas realm with custom login module.

Arjan Tijms

unread,
Feb 19, 2023, 4:19:57 PM2/19/23
to WildFly
Hi,

On Wednesday, February 8, 2023 at 1:47:23 PM UTC+1 tf19 wrote:
Now I am stuck with finding a solution for the next steps:

How can I "redirect" in my secured content after successfully authenticating in the ServerAuthModule?
How can I "redirect" to the Loginform (and proceed with normal authentication) after the authentication with HTTP - Header was not successful?
Is this the correct way to do this?

Maybe the Jakarta Authentication examples listed here can of help: 


Kind regards,
Arjan Tijms

 

tf19

unread,
Feb 20, 2023, 4:51:05 AM2/20/23
to WildFly
Hello, 

thank you so much for your support :) , I got it working to redirect to the secured content automatically after authentication was successful.

But I am still a bit confused, is there a way to combine this mechanism with a login form?
If the needed credentials aren't in the http - header or the authentication fails, the user should have an option to authenticate by entering credentials in a form.

Any help is appreciated, thanks in advance !
Reply all
Reply to author
Forward
0 new messages