[jbossseam-issues] [JBoss JIRA] Updated: (JBSEAM-1009) optionally login-require in a more specific page should be able to override a wildcard login-require

Leo Baschy (JIRA) jira-events at lists.jboss.org
Wed Mar 14 20:16:32 EDT 2007


     [ http://jira.jboss.com/jira/browse/JBSEAM-1009?page=all ]

Leo Baschy updated JBSEAM-1009:
-------------------------------

    Attachment: weaker-explicit-security.patch

New patch file name replaces old file name:

weaker-explicit-security.patch

This got bigger now, but it fulfills a purpose:  Allow good practical security configurations with greater certainty of correctness, partially due to terseness.

Backwards compatibility was a major design factor too.

Illustrated by a use example from our main project.  In real use though we are using .page.xml files (except wildcards) instead of so many page elements.


Security items to look for in the example are:

1) weaker-explicit-security="true"  Without that Seam would be the way it used to be and you can think through which parts then wouldn't work.

2) By wildcard "*" for the whole site some security is being established.

2a) login-required="true" means no viewing if not logged in.

2b) <restrict>#{s:hasPermission('adminStuff', 'basic', null)}</restrict> means unless set otherwise, only those with permission to do adminStuff can see pages.

Note that any directory added anywhere does have at least some security then.  You can't "forget" adding security for a new directory.

Later in project development, with other URLs set, it was decided we needed pages for consumers/subscribers.  Hence

3) By wildcard "/consumer/*" different security is being established.

3a) login-required="true" wasn't really necessary to repeat, but it is ok.

3b) <restrict>#{s:hasPermission('subscriberStuff', 'basic', null)}</restrict> is in effect instead (!) of the adminStuff.

Point is that directory is for consumbers/subscribers.  The rest of the site is for admins, but this directory would not benefit from the "old" Seam way of requiring both restrict tests to pass.

Then we came up with multi-page login.  Depending on where you're trying to go to you get a different login page.  One for admins, one for consumers/subscribers.

There only being one login-view-id we have to dispatch.  You'll recognize that only the login-view-id itself is exempt from login-required.  Hence

4) Several specific pages for login and registration all have an explicit login-required="false".

Different than the "old" Seam way that explicit login-required="false" is effective for that page or wildcard.

4a) And because these pages with explicit login-required="false" don't have an explicit <restrict> themselves, the restrict from any wildcard for them has been overridden too.

A restrict would require login.  If needed it can be put in explicitely and wouldn't be overridden, but what's the intention there?  Useless case, self-contradicting settings.

Note that this gives you the freedom to make any content at any URL available with different <restrict> or even without login, even when the rest of the site remains tight.

Security now is a function of your settings, not unduly limited by relative location logic.

If you are paranoid you can have a script make sure there are no changes to occurrences of login-required and restrict.

5) Not shown in the example there is <restrict>none</restrict>, which allows to override any restriction from a less specific wildcard.

For some time we needed to accompany each login-required="false" with a <restrict>none</restrict>, when that got old we implemented 4a).


The example:

<pages login-view-id="/login/required.xhtml" weaker-explicit-security="true">

 <page view-id="*" login-required="true">
  <restrict>#{s:hasPermission('adminStuff', 'basic', null)}</restrict>
 </page>

 <page view-id="/consumer/*" login-required="true">
  <restrict>#{s:hasPermission('subscriberStuff', 'basic', null)}</restrict>
 </page>

 <page view-id="/login/required.xhtml" login-required="false">
  <action execute="#{loginDispatcher.doDispatch}" />
  <navigation from-action="#{loginDispatcher.doDispatch}">
   <rule if-outcome="consumer">
    <redirect view-id="/consumer/login.xhtml" />
   </rule>
   <rule>
    <redirect view-id="/all/login.xhtml" />
   </rule>
  </navigation>
 </page>

 <page view-id="/consumer/login.xhtml" login-required="false">
  <action execute="#{consumerLogin.tryWithoutForm}" />
  <navigation from-action="#{consumerLogin.tryWithoutForm}">
   <rule if="#{identity.loggedIn}">
    <redirect view-id="/consumer/main/menu.xhtml" />
   </rule>
   <rule if-outcome="new mdn">
    <redirect view-id="/consumer/registration/new.xhtml" />
   </rule>
  </navigation>
  <navigation from-action="#{identity.login}">
   <rule if="#{identity.loggedIn}">
    <redirect view-id="/consumer/main/menu.xhtml" />
   </rule>
  </navigation>
 </page>

 <page view-id="/consumer/registration/new.xhtml" login-required="false">
  <navigation from-action="#{subscriberHome.persist}">
   <rule if-outcome="persisted">
    <end-conversation />
    <redirect view-id="/consumer/main/menu.xhtml" />
   </rule>
  </navigation>
 </page>

 <page view-id="/all/login.xhtml" login-required="false">
  <navigation from-action="#{identity.login}">
   <rule if="#{identity.loggedIn}">
    <redirect view-id="/admin/home.xhtml" />
   </rule>
  </navigation>
 </page>

</pages>


Then there are some implementation details we'd rather not have had to deal with.

To get it out of the way let's mention we don't cause that problem:  If there isn't a login-required but there is a restrict then an exception is thrown that then causes some afterRender to be called when there wasn't a call to beforeRender.

More interestingly, there is some interaction between dom4j and DTDs.  It goes like this:  When pages.xml or a page.xml mentions on of the DTDs that says

<!ATTLIST page login-required (true|false) "false">

then it appears to be impossible to tell via dom4j whether login-required has been set explicitely.  If it hasn't been set it doesn't report null, but "false".  No way to find out what is in the DOM tree.

The effect would be when lacking a explicit login-required then erroneously working like login-required="false" - instead of inheriting from a less specific wildcard - a very bad bug.

That problem goes away when having a DTD with

<!ATTLIST page login-required (true|false) #IMPLIED>

or no (!) DTD mentioned.

Problematic DTDs include at least "-//JBoss/Seam Pages Configuration DTD 1.2//EN" "http://jboss.com/products/seam/pages-1.2.dtd".

The current workaround implemented is if (and only if) weaker-explicit-security="true" then rejecting (log.error and RuntimeException with very clear text) those old DTDs if used.  Does allow use of none or newer.

A second workaround currently coded into the patch, but relatively easy to replace, is to enforce use of same DTD (or none at all) for pages.xml and all whatever.page.xml on whole site.  That one could be replaced with just rejecting the old DTDs but not caring whether all are the same.  I'll be happy to make that change and test it, but I didn't want to sit on this patch any longer before submitting it.

> optionally login-require in a more specific page should be able to override a wildcard login-require
> ----------------------------------------------------------------------------------------------------
>
>                 Key: JBSEAM-1009
>                 URL: http://jira.jboss.com/jira/browse/JBSEAM-1009
>             Project: JBoss Seam
>          Issue Type: Patch
>          Components: Security
>    Affects Versions: 1.2.0.GA
>         Environment: all
>            Reporter: Leo Baschy
>         Assigned To: Shane Bryzak
>         Attachments: may-override-login-required.patch, may-override-login-required.patch, weaker-explicit-security.patch
>
>
> This should be optional to switch on, so no one's existing expectations of security get broken.
> The point is about having a generic wildcard  <page view-id="*" scheme="http" login-required="true">  to secure the whole site, and then allowing specific pages or specific wildcards to have login-required="false".  E.g. for a registration (with preview) section as one cannot be logged in if one isn't registered yet.
> Some may suggest instead forcing pages into dedicated secure and not-secure directories, but in reality if there are multiple reasons to force pages into directories different ways (security, hyperlink management, publishability of URLs, etc.), one cannot serve all of them.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.jboss.com/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the seam-issues mailing list