You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Remon Sadikni <re...@zmaw.de> on 2011/10/19 13:57:43 UTC

Re: combination of RemoteAddrValve und basic authentication

Hi André, hi Christopher,
>>>
>>> The use of HTTP BASIC authentication confuses things here because
>>> of the credential transfer mechanism (HTTP headers). I suppose
>>> you could write a Valve that sniffs the user's IP address and
>>> then adds HTTP headers to the request for the "Authentication"
>>> header to essentially force a login. You'll have to decide what
>>> the user's Principal will need to look like (because Tomcat will
>>> actually try to /verify/ the fake-user's credentials and maintain
>>> a "login" for them, running proper authorization checks, etc.) in
>>> order to actually work.
>>

I managed to get it working. If you are interested in my solution for 
Tomcat 6: I extended the Valve RequestFilterValve and overwrote the 
method process with this content:

// Check the allow patterns
for (int i = 0; i < allows.length; i++) {
   if (allows[i].matcher(property).matches()) {
     // create a principal for an existing fake user
     final List<String> roles = new ArrayList<String>();
     roles.add("ROLE");
     final Principal principal = new GenericPrincipal(null, "USER", 
"PASS", roles);
     // set the principal in this request
     request.setUserPrincipal(principal);
   }
}
// pass this request to the next valve (basic authentication)
getNext().invoke(request, response);
return;

If the User has an allowed IP address, the UserPrincipal will be set in 
this request, so that the next valve (the Basic Authentication) will not 
show the login window. If the User has another IP address, the request 
will be forwarded to the next valve without any changes, so that you 
need to log in.

At first I tried solving it with RequestWrappers and changing Headers, 
but that failed, because the Basic Authentication Method tests for the 
UserPrincipal.

Thanks for your help,
Remon

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: combination of RemoteAddrValve und basic authentication

Posted by Remon Sadikni <re...@zmaw.de>.
Hi Chris,

>> but "allows" is part of RequestFilterValve.
>
> Not in the current trunk. Your code expects the "allows" variable to
> be of type String[], and no such variable exists in RequestFilterValve.

> Right: the point of the RequestFilterValve is that you don't have to
> override the process() method. Overriding it kind of defeats the
> purpose of the class, because it really doesn't have any other methods
> other than the accessors and mutators for the 'deny' and 'allow'
> properties.
>

I only mentioned once, that I use Tomcat 6: And there is an "allows" 
attribute and an additional method "precalculate".

Regards,
Remon

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: combination of RemoteAddrValve und basic authentication

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Remon,

On 10/19/2011 12:23 PM, Remon Sadikni wrote:
> Hi Chris,
>> 
>> If you overrode the process() method (and I'm sure you changed
>> other things, too, since the variable "allows" is not part of 
>> RequestFilterValve), then you really aren't getting anything by 
>> extending RequestFilterValve.
> 
> but "allows" is part of RequestFilterValve.

Not in the current trunk. Your code expects the "allows" variable to
be of type String[], and no such variable exists in RequestFilterValve.

> I only extended this class. I took the same invoke() method as
> RequestAddrValve, so that I get the IP-address of the user:
> 
> public void invoke(Request request, Response response) throws
> IOException, ServletException { 
> process(request.getRequest().getRemoteAddr(), request, response); 
> }
> 
> and overwrote the process method to react on this IP address.

Right: the point of the RequestFilterValve is that you don't have to
override the process() method. Overriding it kind of defeats the
purpose of the class, because it really doesn't have any other methods
other than the accessors and mutators for the 'deny' and 'allow'
properties.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk6fEtAACgkQ9CaO5/Lv0PAVagCdGCDoraUl41tI7H9hgKxIPkqU
AvwAoLV9OW95mDaPVXL7vibCfWo5Yokj
=4oGY
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: combination of RemoteAddrValve und basic authentication

Posted by Remon Sadikni <re...@zmaw.de>.
Hi Chris,
>
> If you overrode the process() method (and I'm sure you changed other
> things, too, since the variable "allows" is not part of
> RequestFilterValve), then you really aren't getting anything by
> extending RequestFilterValve.

but "allows" is part of RequestFilterValve. I only extended this class. 
I took the same invoke() method as RequestAddrValve, so that I get the 
IP-address of the user:

  public void invoke(Request request, Response response)
         throws IOException, ServletException {
    process(request.getRequest().getRemoteAddr(), request, response);
  }

and overwrote the process method to react on this IP address.

>
> Note that there has been some grumbling on the list about the use of
> Matcher.matches() instead of Matcher.lookingAt(): you might want to
> consider your requirements before choosing one over the other: most
> regular expression folks will expect the behavior of lookingAt and not
> matches().

I will look at it.

> Hey, that's an idea: I didn't think of just shoving the principal into
> the request. Just be aware that you will do this on every request,
> because Tomcat isn't storing the Principal anywhere to maintain the
> "login".

That's ok for me.

Regards,
Remon

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: combination of RemoteAddrValve und basic authentication

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Remon,

On 10/19/2011 7:57 AM, Remon Sadikni wrote:
> I managed to get it working. If you are interested in my solution
> for Tomcat 6: I extended the Valve RequestFilterValve and overwrote
> the method process with this content:
> 
> // Check the allow patterns for (int i = 0; i < allows.length; i++)
> { if (allows[i].matcher(property).matches()) { // create a
> principal for an existing fake user final List<String> roles = new
> ArrayList<String>(); roles.add("ROLE"); final Principal principal =
> new GenericPrincipal(null, "USER", "PASS", roles); // set the
> principal in this request request.setUserPrincipal(principal); } } 
> // pass this request to the next valve (basic authentication) 
> getNext().invoke(request, response); return;

If you overrode the process() method (and I'm sure you changed other
things, too, since the variable "allows" is not part of
RequestFilterValve), then you really aren't getting anything by
extending RequestFilterValve.

Note that there has been some grumbling on the list about the use of
Matcher.matches() instead of Matcher.lookingAt(): you might want to
consider your requirements before choosing one over the other: most
regular expression folks will expect the behavior of lookingAt and not
matches().

> If the User has an allowed IP address, the UserPrincipal will be
> set in this request, so that the next valve (the Basic
> Authentication) will not show the login window. If the User has
> another IP address, the request will be forwarded to the next valve
> without any changes, so that you need to log in.

Hey, that's an idea: I didn't think of just shoving the principal into
the request. Just be aware that you will do this on every request,
because Tomcat isn't storing the Principal anywhere to maintain the
"login".

> At first I tried solving it with RequestWrappers and changing
> Headers, but that failed, because the Basic Authentication Method
> tests for the UserPrincipal.

It should be doing both, but the Principal is more efficient because
you don't have to use  "real" user that can be authenticated using the
webapp's Realm.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk6e3RcACgkQ9CaO5/Lv0PCIQQCdGKJ3w7mLQqir8wDswf2b/Np2
x0cAoKzOb5X9Ka/BRpeWzEWie0UMCQqQ
=3Qln
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org