4

I need to define security-constraints for three different sections of my webapplication. One for /admin/*, one for /account/* and a tricky one. This last one should match everything except the preceding url-patterns (/* excluding /admin/* and /account/*). How do I create this constraint?

  <security-constraint>
    <web-resource-collection>
        <web-resource-name>AdminPanel</web-resource-name>
        <url-pattern>/admin/*</url-pattern>
    </web-resource-collection>      
    <auth-constraint>
        <role-name>admin</role-name>
    </auth-constraint>
    <user-data-constraint>      
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
  </security-constraint>

  <security-constraint>
    <web-resource-collection>
        <web-resource-name>AccountPanel</web-resource-name>
        <url-pattern>/account/*</url-pattern>
    </web-resource-collection>      
    <auth-constraint>
        <role-name>account</role-name>
    </auth-constraint>
    <user-data-constraint>      
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
  </security-constraint>

  <security-constraint>
    <web-resource-collection>
        <web-resource-name>HTTPSOnly</web-resource-name>
        <url-pattern>`/* excluding /admin/*, /account/*`</url-pattern>
    </web-resource-collection>      
    <auth-constraint>
        <role-name>visitor</role-name>
    </auth-constraint>
    <user-data-constraint>      
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
  </security-constraint>
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Menno
  • 12,175
  • 14
  • 56
  • 88
  • 1
    I'm not sure if I understand your concrete problem. Just specifying `/*` should work as per the standard Servlet API URL pattern matching rules (e.g. `/admin/*` is more specific than `/*` and thus its constraint will be used instead). Have you tried it and how exactly did it fail? – BalusC Apr 02 '13 at 12:34
  • Well, I am trying to exclude `/admin/*` and `/account/*` so I will be able to use these roles to determine if someone is allowd to `/admin/*` based on his role. A `url-pattern`=/* would suffice to require an HTTPS connection, but it would not stop a regular user from accessing `/admin/*`. Or would it, since it's excluded on the first rule? – Menno Apr 02 '13 at 15:23
  • 1
    As per your config, the `/admin/*` requires a role of `admin`, not `visitor`. Since `/admin/*` is more specific than `/*`, it wins (see servlet 3.0 spec chapter 12.1). Simple as that. Now, have you tried it and how exactly did it fail? If you didn't have tried it at all, then this question should actually be closed as "rhetorical". Please rewrite the question accordingly. – BalusC Apr 02 '13 at 15:24
  • love how this question broke SO's syntax highlighter... @BalusC section 12.1 of the spec is about mapping requests to Servlets, not about combining security constraints. This I found under 13.8.1 and is as clear as mud. Practically security constraints are merged in a way I find not quite palatable. – Peter Perháč Mar 21 '15 at 23:19

1 Answers1

1

You have three distinct roles defined viz. admin, account and visitor.

Your first constraint says that only admin role can access resources in /admin/*

Your second constraint says that only account can access resources in /account/*

At this point (without third constraint) imagine a visitor role(or any other role for that matter) tries to access anything in admin and account directories. Due to the first 2 rules it won't be able to access it. It will only be able to access resources outside admin and account directories.

So what you want is already achieved by the first 2 constraints and in my opinion you don't require a 3rd constraint.

prashant
  • 1,805
  • 12
  • 19
  • The 3rd constraint is necessary because "other" resources require the `visitor` role. If you omit the 3rd constraint, **anyone** would be able to access "other" resources. – BalusC Apr 02 '13 at 12:59
  • What you say is right in case **Visitor** is different from **anyone**. I was assuming that visitor role is equivalent to anyone (stemmed from the kind of access asked for). If visitor is distinct from anyone then are there any resources protected from anyone but accessible to visitor? I think not. – prashant Apr 02 '13 at 13:06
  • "Anyone" has as per spec a role of `*`, not `visitor`. – BalusC Apr 02 '13 at 13:09
  • What you suggest is correct. My question is that do we really need to protect every single resource from a stray visitor(anyone)? If it is implemented as you suggest then **anyone** will not be able to access any resource. I guess this really depends on the requirement of the application. – prashant Apr 02 '13 at 13:20
  • @prashant, my naming of `visitor` was indeed incorrect and should be `*` as BalusC mentioned. Though I'm using `SSL` everywhere so the user will never be able to go back to `HTTP` (login, then visit index or something). This would result in a vulnerable cookie and so on, leaving the data open for a `man-in-the-middle`. Otherwise I'd have to determine if the user is logged in and send him to `https://...` instead of `http://...`. – Menno Apr 02 '13 at 15:31