Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [jetty-dev] Re: Security Constraints problem

For those following along, Greg has added a new junit test for urls
like "/j_security_check" in org.eclipse.jetty.security.Constrain2tTest.java.

Greg,

The new junit test is correct for the urls, but does not mirror the situation
with the Authenticators that is setup for a WebAppContext.

Your test has:

_securityHandler.setAuthenticator(new SessionCachingAuthenticator(
                 new FormAuthenticator("/testLoginPage","/testErrorPage")));

But the WebAppContext has:

_securityHandler.setAuthenticator(new DeferredAuthenticator(
                new SessionCachingAuthenticator(
                   new FormAuthenticator("/testLoginPage","/testErrorPage"))));


If you replace with the setup above, then the test will also fail, with a 200 OK instead of the 302 redirect. This is a different failure to my webapp, and caused because you have a RequestHandler at the bottom of the handler chain, and when the SecurityHandler.handle() chains through to this handler, it will explicitly cause any DeferredAuthenticators to be called:

  if (request.getAuthType()==null || "user".equals(request.getRemoteUser()) || request.isUserInRole("user"))


My webapp, however, will chain through to the ServletHandler, and thus doesn't trigger any
authenticators, so tries to serve /j_security_check as static content.

The basic cause of failure in both cases, however, remains the fact that there are
no constraints considered to match "/j_security_check", causing isMandatory to be
false, and thus causing the DeferredAuthenticators to defer authentication.


regards,
Jan


Jan Bartel wrote:
Putting in a constraint for j_security_check wound up with a loop back to the login page:


Security constraint:

Handling the j_security_check request:
--------------------------------------
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: {RoleInfo,C[roleA]}
isAuthMandatory=true for Request.getRequestURI= /test-jaas/j_security_check
FormAuthenticator.validateRequest with Request.getRequestURI = /test-jaas/j_security_check
FormAuthenticator.validateRequest with Request.getPathInfo = null
FormAuthenticator.validateRequest with Request.getContextPath = /test-jaas
FormAuthenticator.validateRequest with Request.getServletPath = /j_security_check
FormAuthenticator.validateRequest with Request.getQueryString = null
FormAuthenticator.validateRequest, dispatching request /test-jaas/j_security_check with forward to /login.html

The decision to do the authentication is triggered off the
pathInfo, but it seems in this case that the /j_security_check is considered the servletPath rather than the pathInfo?!


Jan





Greg Wilkins wrote:
It looks like it does not handle j_security_check being outside of the constraints.
It is deferring handling of it!!!

So a simple hacky fix would be to always insert a constraint for j_security_check,
but I'm wondering if there is something more elegant ???

cheers



Jan Bartel wrote:
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



---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email







--
Jan Bartel, Webtide LLC | janb@xxxxxxxxxxx | http://www.webtide.com


Back to the top