Hi,
A long, long standing request in Jakarta Authentication is to register just a server auth module with the factory. I traced this request all the way back to even before the spec was released, as Anil Saldanha was asking for it back then.
There's various options to fulfill this request, with multiple variants even where the caller provides the layer, context ID, in various forms, etc etc. I'm however leaning towards the use case which seems to be the 99% use case: register a serverAuthModule for the current web application.
Though Jakarta Authentication is technically API independent (e.g. it has no Servlet dependencies in the API), I think the easiest way to not tire the user with creating a context ID is to have a method of the following form:
public abstract String registerServerAuthModule(ServerAuthModule serverAuthModule, Object context);
public abstract removeServerAuthModule(Object context);
Where "context", just as the RequestMessage in MessageInfo is a profile specific type, so the API itself remains neutral.
An implementation could then be something like the following:
public String registerServerAuthModule(ServerAuthModule serverAuthModule, Object context) {
if (context instanceof ServletContext servletContext) {
String registrationId = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return AuthConfigFactory.getFactory().registerConfigProvider(
new DefaultAuthConfigProvider(serverAuthModule),
"HttpServlet",
getAppContextID(servletContext),
"Default single SAM authentication config provider");
}
});
// Remember the registration ID returned by the factory, so we can unregister module when the web module is undeployed.
servletContext.setAttribute(CONTEXT_REGISTRATION_ID, registrationId);
return registrationId;
} else {
throw UnsupportedException(...);
}
}
With the remove implementation being e.g.
public void removeServerAuthModule(Object context) {
if (context instanceof ServletContext servletContext) {
String registrationId = (String) servletContext.getAttribute(CONTEXT_REGISTRATION_ID);
if (!isEmpty(registrationId)) {
AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
public Boolean run() {
return AuthConfigFactory.getFactory().removeRegistration(registrationId);
}
});
} else {
throw UnsupportedException(...);
}
}
The above used getAppContextID(servletContext) could become a public method as well, but that's optional.
Thoughts?
Kind regards,
Arjan Tijms