-
-
Save sguilhen/90b862a145e4d47a4d5d to your computer and use it in GitHub Desktop.
JASPIC implementation issues
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
After reviewing the JASPIC tests in Arun Gupta's testsuite and comparing them with our implementation I've | |
identified a number of issues and missing bits that are not tested by the TCK. | |
The testsuite contains a few modules: | |
** basic-authentication: checks if access to a protected web application is correctly granted/denied to | |
users. With a proper security domain in place all tests in this module pass. | |
** ejb-propagation: checks if the authenticated user is propagated by the container to the EJB layer. We | |
have a couple of failures here. The JASPI callback handler correctly populates the security context and | |
the context is propagated to the EJB layer. However, the test assumes that the EJBs will be called | |
*without* authenticating the user again as it expects the container will trust the authentication performed | |
by the web layer. WF throws an exception denying access as the incoming security context has not been | |
validated by the EJB layer (it uses the "other" security domain and that domain rejects all authentication | |
attempts by default) | |
So problem here is that right now we don't have that kind of trust between layers - the EJB layer will | |
always authenticate the incoming principal. While we could get around the failures by setting up a security | |
domain for the EJBs, I think this might be a good oportunity to think about a better mechanism in which the | |
EJB authentication is skipped when the incoming security context corresponds to a user that has already | |
been authenticated. | |
** lifecycle: checks if the JASPI modules are called when they should. Exemples include the | |
validateRequest/secureResponse pair that must be invoked for every request and cleanSubject that should be | |
called when a HttpServletRequest.logout() is performed. | |
We have several issues here. The first has to do with secureResponse. While it *is* always called, the call | |
happens at a stage in which its to late to write anything to the response because it has already been | |
committed. The JASPIAuthenticationMechanism is incorrectly using an ExchangeCompletionListener to invoke | |
the secureResponse method, which pretty much renders secureResponse useless. The question here is what can | |
we do to invoke secureResponse after the servlet is done writting but before the response is committed? | |
The second issue we have here is that HttpServletRequest login(), logout() and authenticate() are ignoring | |
JASPIC. The implementation should be using the AuthConfigFactory to check if there is an AuthConfigProvider | |
for the "HttpServlet" layer and the servlet appContextId. If a provider is found, it should be used to | |
(according to the spec): | |
* throw an exception if login() is called. | |
* call validateRequest if authenticate is called. This might be working as the code seems to be calling | |
the configured JASPIC mechanism when authenticate is performed. The mech will do the whole | |
validateRequest/secureResponse processing. | |
* call cleanSubject if logout() is called. This is definitely not working as the HttpServletRequestImpl | |
ignores JASPIC. | |
** register-session: checks if the authenticated user is "remembered" by the container when the javax.servlet.http.registerSession property is set by the JASPIC module in the MessageInfo. In other words, | |
the container must store the authenticated Principal, its roles, etc so that they are restored in | |
subsequent requests. JASPIC modules will still be called and they should be able to do | |
request.getUserPrincipal() to retrieve the principal restored by the container. | |
I'm haven't really looked into this particular scenario yet so I'm not sure how to do this in Undertow. | |
Perhaps calling authenticationComplete() with cachingRequired=true is enough to remember the authenticated | |
Account? | |
A related issue has to do with the getAuthType() implementation that should also check if the JASPIC | |
module has set the javax.servlet.http.authType property in the MessageInfo. This is what the spec says: | |
"When getAuthType is to return a non-null value, the Map of the MessageInfo object used in the call to | |
validateRequest must be consulted to determine if it contains an entry for the key identified in Table 3-3. | |
If the Map contains an entry for the key, the corresponding value must be obtained from the Map and | |
established as the getAuthType return value. If the Map does not contain an entry for the key, and an auth- | |
method is defined in the login-config element of the deployment descriptor for the web application, the | |
value from the auth-method must be established as the getAuthType return value. If the Map does not contain | |
an entry for the key, and the deployment descriptor does not define an auth-method, a product defined default | |
non-null value must be established the getAuthType return value, and the same default value need not be used | |
for both cases." | |
Right now the mechanis always returns "JASPI" as the authType, which is clearly wrong. In order to properly | |
implement this I would need access to the auth-method that has been configured for the servlet but that | |
information is not available in the exchange or the ServletRequestContext (at least I couldn't find it). | |
DeploymentManagerImpl uses the auth-method to instantiate the corresponding mechanims but when JASPIC is | |
used this information is lost and as a result I can't change the mech to properly implement the | |
getAuthType() method. | |
** wrapping: checks whether request/response objects that have been wrapped by JASPIC modules reach the | |
servlet in its wrapped form. The JASPIC mech didn't handle this scenario but I've already implemented the | |
code to deal with wrapped requests and this module is passing. | |
Then there's configuration. Right now we rely on a security domain that contains a jaspic configuration to | |
enable JASPIC for a web application. This might look ok but as Arjan pointed out JBoss/WF is the only | |
container out there that requires special configuration to enable JASPIC. Applications can register | |
AuthConfigProviders dynamically by using the AuthConfigFactory and they shouldn't need a security domain | |
if they will be delegating auth decisions to a provider that has been dynamically registered. | |
In runtime the container should use the AuthConfigFactory to check if there is a registered AuthConfigProvider | |
for the "HttpServlet" layer and corresponding servlet appContextId. If such provider is found, then JASPIC | |
authentication is to be performed. If not, container-specifc mechanisms are used. Right now we don't have | |
a way in Undertow to dynamically select the mechanisms that should be used (or at least I haven't found a | |
way to do that) so I would like to know your thoughts on this. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment