Restrict access to certain user groups when using the NegotiateSecurityFilter

Jul 19, 2010 at 12:03 PM
I'm just checking Waffle and like to use the NegotiateSecurityFilter (I'm trying to replace jcifs). http://code.dblock.org/ShowPost.aspx?id=106 Is it possible to restrict the access to certain user groups in the filter configuration? As far as I understand the documentation, everyone is accepted, as long as it's a successful Windows login. If not, what's the best way to do this? Should my application get the users groups with ((WindowsPrincipal) request.getUserPrincipal()).getGroups(); and check if the allowed goup exist.
Coordinator
Jul 19, 2010 at 1:29 PM

It's not possible in the filter configuration.

The recommended way is always to separate authentication and authorization. Let the filter do the work and supply authentication. Use the web server to do authorization. If, for example, you're using Tomcat, you can use the standard security-contraint mechanism with Waffle.

<security-constraint>
    <display-name>Waffle Security Constraint</display-name>
    <web-resource-collection>
      <web-resource-name>Protected Area</web-resource-name>
      <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>Everyone</role-name>
    </auth-constraint>
  </security-constraint>

In this case everything is protected and you need to be a logged in user (Everyone group) to access the pages.

Jul 19, 2010 at 5:09 PM

Ok, sounds good. I'm using Tomcat and tried to get it working with the waffle-filter sample, but apparently I'm doing something wrong.

Without the security-constraint the waffle-filter webapp recognizes my user. Now I check if my user has been granted the role "Jeder" (means "Everyone"; I'm on a german system) and it tells me, that I have been granted the role "Jeder".

Now I add the security-contraint to the web.xml of the waffle-filter:

<security-constraint>
  <display-name>Waffle Security Constraint</display-name>
  <web-resource-collection>
   <web-resource-name>Protected Area</web-resource-name>
   <url-pattern>/*</url-pattern>
  </web-resource-collection>
  <auth-constraint>
   <role-name>Jeder</role-name>
  </auth-constraint>
</security-constraint>

 Tomcat tells me: "HTTP Status 403 - Access to the requested resource has been denied"

Any idea what I'm doing wrong? I'm using Apache Tomcat/6.0.28 on Windows 7 (without a Active Directory).

Coordinator
Jul 19, 2010 at 5:49 PM

This looks odd. The only idea I have now is that maybe you do need to declare the Jeder role. Also I would put the filter in debug and make sure it adds a role called "Jeder", spelled the same and stuff like that. I'll check this out when I get a chance.

<security-role>
  <role-name>Jeder</role-name>
</security-role>

 

Jul 19, 2010 at 6:49 PM

I have added the security-role but it doesn't makes a difference.

In the logs I see that the NegotiateSecurityFilter gets initialized and started and finally catalina is started. If I now call the app, there is no further log statement, so I think that tomcat evaluates the security-constraint before calling the filter. Thus the filter gets never called and Tomcat answers with a 403. If I remove the secure-constraint, everything works as expected, and I can see the groups (roles) of the current user printed to the logfile.

Coordinator
Jul 20, 2010 at 12:34 AM

Ok. I lied. I got confused with all these options. Tomcat has its whole authentication + authorization mechanism based on Realms. It’s a whole other beast to pass authentication from a filter onward to Tomcat’s realms. It would force the filter to become Tomcat-specific, so we’ll leave it as is (filter is for any server that implements servlets).

The Tomcat way of doing authentication is a valve (a sort of a Tomcat filter). Remove the filter and use the Waffle valve in context.xml . There’s a sample called waffle-negotiate.

<?xml version='1.0' encoding='utf-8'?>
<Context>
  <Valve className="waffle.apache.NegotiateAuthenticator" />
  <Realm className="waffle.apache.WindowsRealm" />
</Context>

Let me know if this works.

Jul 20, 2010 at 9:12 AM

Yes it works, if I use the valve instead of the filter (waffle-negotiate). Thanks for your help.

A difference I have seen using the waffle-negotiate vs. the waffle-filter is, that if I use waffle-negotiate, I have to deploy all the jar files (waffle-jna.jar, platform.jar, jna.jar, commons-logging-1.1.1.jar) to the tomcat/lib/ directory. Otherwise the webapp is not starting. When using the waffle-filter, I can choose to deploy the jars to the webapps lib directory /waffle-filter/WEB-INF/lib/. I like this option, because it makes the deployment easier, so I'm thinking about using the NegotiateSecurityFilter and handling the group restrictions inside my application (by checking the users groups at the login).

Coordinator
Jul 20, 2010 at 12:17 PM

That's right. According to Tomcat valve classes have to be in common/lib or common/classes or server/lib or server/classes. I think Tomcat 7 is moving away from valves and using filters for everything - which, I suppose, would fix this problem.

I guess you can't have it all :)