I previously had some code working on Glassfish, but I want to port it to WildFly.
However, I cannot seem get the module to be invoked by WildFly. The ServletContextListener
initializes the module as follows
AuthConfigFactory.getFactory() .registerConfigProvider(new OpenIdConnectModuleConfigProvider(options, null), "HttpServlet", getAppContext(sce), null);
"HttpServlet"
is not Glassfish specific and appears to be referenced in https://github.com/wildfly/wildfly/blob/master/undertow/src/main/java/org/wildfly/extension/undertow/security/jaspi/JASPIAuthenticationMechanism.java?source=cc
Glassfish does not require a <logon-config>
block on the web.xml
and putting any variant in WildFly does not work (as expected)
The other place I am suspecting is how I calculate the application context identifier. For Glassfish I had
private String getAppContext(final ServletContextEvent sce) {
return sce.getServletContext()
.getVirtualServerName() + " "
+ sce.getServletContext()
.getContextPath();
}
Could it be different in WildFly? Though I saw the similar code in https://github.com/rdebusscher/secSpikeWeb/blob/master/src/main/java/org/omnifaces/security/jaspic/core/Jaspic.java#L300 as well
I have also tried adding to standalone.xml
this block
<security-domain name="jaspi" cache-type="default">
<authentication-jaspi>
<login-module-stack name="dummy">
<login-module code="Dummy" flag="optional"/>
</login-module-stack>
<auth-module code="org.wildfly.extension.undertow.security.jaspi.modules.HTTPSchemeServerAuthModule" flag="required"/>
</authentication-jaspi>
</security-domain>
And set <default-security-domain value="jaspi"/>
However it had no effect and putting a breakpoint in the module didn't show that it gets hit either.
In addition, there I couldn't find a to be a way of doing the following, in WildFly like I would in glassfish-web.xml
but that can be another question
<security-role-mapping>
<role-name>users</role-name>
<group-name>https://helloworld</group-name>
</security-role-mapping>
The code is pretty big, but the gist of it can be found in
https://github.com/trajano/openid-connect/tree/openid-connect-1.0.1/openid-connect-jaspic-module
and
https://github.com/trajano/openid-connect/tree/openid-connect-1.0.1/openid-connect-jaspic-sample
Note I am looking for it on the application level and not set a global server JASPI.
"HttpServlet" is not Glassfish specific
That's correct, AFAIK this is a standard identifier to say for which subsystem in Java EE the auth module is going to be registered. But there's only one other valid value and that's something with "soap" in it (not sure).
Could it be different in WildFly?
No, it's a standard way.
And set
<default-security-domain value="jaspi"/>
The recommended way should be this in standalone.xml
:
<security-domain name="jaspitest" cache-type="default">
<authentication-jaspi>
<login-module-stack name="dummy">
<login-module code="Dummy" flag="optional"/>
</login-module-stack>
<auth-module code="Dummy"/>
</authentication-jaspi>
</security-domain>
And then putting the following in WEB-INF/jboss-web.xml
:
<jboss-web>
<security-domain>jaspitest</security-domain>
</jboss-web>
This should be enough. It's what I use on WildFly 8.2 and 9.0, and it's what the Java EE samples project uses. But setting the default domain should also really work as you did, and you activation code is close enough too, so I'm not sure if the above will make a difference in your case.
Alternatively there's a JBoss specific programmatic way to activate JASPIC:
String securityDomain = "other";
IdentityManager identityManager = deploymentInfo.getIdentityManager();
if (identityManager instanceof JAASIdentityManagerImpl) {
try {
Field securityDomainContextField =
JAASIdentityManagerImpl.class.getDeclaredField("securityDomainContext");
securityDomainContextField.setAccessible(true);
SecurityDomainContext securityDomainContext =
(SecurityDomainContext)
securityDomainContextField.get(identityManager);
securityDomain =
securityDomainContext.getAuthenticationManager().getSecurityDomain();
} catch (NoSuchFieldException | SecurityException |
IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
ApplicationPolicy applicationPolicy = new
ApplicationPolicy(securityDomain);
JASPIAuthenticationInfo authenticationInfo = new
JASPIAuthenticationInfo(securityDomain);
applicationPolicy.setAuthenticationInfo(authenticationInfo);
SecurityConfiguration.addApplicationPolicy(applicationPolicy);
deploymentInfo.setJaspiAuthenticationMechanism(new
JASPIAuthenticationMechanism(securityDomain, null));
deploymentInfo.setSecurityContextFactory(new
JASPICSecurityContextFactory(securityDomain));
You need to execute that from a io.undertow.servlet.ServletExtension
It's a shame that JBoss requires JASPIC to be activated. But one of the above shown methods should really work. I just verified them on a stock WildFly 9.0 and it worked there. The validateRequest
method of a testing SAM is called correctly.