Using jetty-7 trunk, there appears to be either a problem with the
way the
applicable constraints are calculated by the
ConstraintSecurityHandler, or
a problem with my understanding of security constraints. As the
latter is
just as likely as the former, I'll explain what's happening :)
I have a webapp with a single security constraint and login-config:
<security-constraint>
<web-resource-collection>
<web-resource-name>JAAS Role</web-resource-name>
<url-pattern>/auth.html</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>roleA</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>Test JAAS Realm</realm-name>
<form-login-config>
<form-login-page>
/login.html
</form-login-page>
<form-error-page>
/authfail.html
</form-error-page>
</form-login-config>
</login-config>
So, hitting a url of /auth.html, I expect to see the login form from
/login.html. When I click submit and the credentials
and role are ok, I expect to be redirected back to /auth.html.
At least, that's what used to happen in jetty-6.
What I see with jetty-7 is:
Hitting /auth.html gives me the form from login.html. So far
so good. However, submitting that produces the error:
HTTP ERROR 404
Problem accessing /test-jaas/j_security_check. Reason:
Not Found
What is happening is that when the form is submitted,
the ConstraintSecurityHandler tries to find some
matching constraints for the url /j_security_check and
naturally doesn't find any - the security constraint is
only on /auth.hml.
Here's the annotated trace of what goes wrong:
Handling the request for the protected page:
------------------------------------------
SecurityHandler.handle with Request.getRequestURI=/test-jaas/auth.html
Preparing Constraint Info for pathIncontext: /auth.html
There are mappings: httpMethod= GET RoleInfo=null
RoleInfo now: {RoleInfo,C[roleA]}
isAuthMandatory=true for Request.getRequestURI= /test-jaas/auth.html
FormAuthenticator.validateRequest with Request.getRequestURI =
/test-jaas/auth.html
FormAuthenticator.validateRequest with Request.getPathInfo = null
FormAuthenticator.validateRequest, dispatching request
/test-jaas/auth.html with forward to /login.html
Handling the form submission:
-----------------------------
SecurityHandler.handle with
Request.getRequestURI=/test-jaas/j_security_check
Preparing Constraint Info for pathIncontext: /j_security_check
There are mappings: httpMethod= POST RoleInfo=null ******
RoleInfo now: null ******
SecurityHandler.checkUserDataPermissions: No constraint info
isAuthMandatory=false for Request.getRequestURI=
/test-jaas/j_security_check
authentication =
org.eclipse.jetty.security.authentication.DeferredAuthenticator$DeferredAuthentication
Note that there are no constraints matching /j_security_check at the
line marked with "*******".
Now, compare and contrast to the test-jetty-webapp, which has a
wild-card set of resources protected by this security constraint:
<security-constraint>
<web-resource-collection>
<web-resource-name>Admin Role</web-resource-name>
<url-pattern>/dump/auth/admin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>Test Realm</realm-name>
<form-login-config>
<form-login-page>/logon.html?param=test</form-login-page>
<form-error-page>/logonError.html?param=test</form-error-page>
</form-login-config>
</login-config>
The annotated trace of this is:
Handling the request for the protected page:
------------------------------------------
SecurityHandler.handle with Request.getRequestURI=/dump/auth/admin/
Preparing Constraint Info for pathIncontext: /dump/auth/admin/
There are mappings: httpMethod= GET RoleInfo=null
RoleInfo now: {RoleInfo,C[admin]}
SecurityHandler.checkUserDataPermissions: No dataconstraint or is none
isAuthMandatory=true for Request.getRequestURI= /dump/auth/admin/
FormAuthenticator.validateRequest with Request.getRequestURI =
/dump/auth/admin/
FormAuthenticator.validateRequest with Request.getPathInfo =
/auth/admin/
FormAuthenticator.validateRequest, dispatching request
/dump/auth/admin/
with forward to /logon.html?param=test
Handling the form submission:
-----------------------------
SecurityHandler.handle with
Request.getRequestURI=/dump/auth/admin/j_security_check
Preparing Constraint Info for pathIncontext:
/dump/auth/admin/j_security_check
There are mappings: httpMethod= POST RoleInfo=null
****** RoleInfo now: {RoleInfo,C[admin]} *************
SecurityHandler.checkUserDataPermissions: No dataconstraint or is none
isAuthMandatory=true for Request.getRequestURI=
/dump/auth/admin/j_security_check
FormAuthenticator.validateRequest with Request.getRequestURI =
/dump/auth/admin/j_security_check
FormAuthenticator.validateRequest with Request.getPathInfo =
/auth/admin/j_security_check
Is a j_security_check: /auth/admin/j_security_check
Logging in
The line marked with "******" shows that because the constraint is on
the directory /admin/*
it matches security constraints, whereas my constraint is on a single
file, and therefore
the /j_security_check url does not match any constraints.
Have I created a stupid and unrealistic situation by protecting a
single
file like this? Or do we need to take a closer look at the way the
constraint matching is done?
cheers
Jan