Re: TrustedPrincipalAuthorizor (extends AuthenticatorBase) Discussion / Comments

2007-12-27 Thread Louis

Christopher Schultz wrote:

Louis wrote:
  

When trying to decide which Authentication I should use I reviewed the
source for the existing ones and realized that none of them would work.
The existing authenticators all check to see if a principal is already
in the request. If it is then the user has already been authenticated
and the authenticator never goes to the Realm to see what permissions /
roles the user has.



That's not how it's supposed to work; authentication and authorization
are separate. Without looking at the source (don't have it handy right
now), the flow ought to be:

- - Determine authentication and authorization requirements
  based upon request URL
- - Check request for principal
  |- if not found, check request for credentials
  |   - if found, load principal into request
  |   - if not found, display login challenge and exit
- - Use found principal for authorization (check roles)

Tomcat's built-in Principal and Request objects conspire to correctly
wire HttpServletRequest.isUserInRole to something within the Principal.
If you choose to gather your Principal information from somewhere else
(NTLM), then you need to take care to play along with Tomcat's notion of
where roles are stored.

If Tomcat does not use the HttpServletRequest.isUserInRole method to
perform its authorization, then you will need to pay attention to the
way it /does/ check for the roles.

  

Since the IIS connector plugs-in a Principal for the
user, this effectively short-circuited the ability of the container to
bind roles to the user.



You should be able to wrap that Principal in some other object if necessary.

  

My solution was to code my own TrustedPrincipalAuthorizor (extends
AuthenticatorBase). I called it an authorizor since it wasn't doing any
actual Authentication.



Is it doing any authorization, or is it just attaching roles to a
Principal and allowing Tomcat to perform the authorization?

  

This class checks for the existence of a
principal in the request. It then uses that principal as the key to tell
the security realm to lookup the users permissions and bind them into
the container for this request.



That seems a little time-consuming to do for every request. Since you're
working with Tomcat's internals, why not permanently attach the role
information to the Principal object one time?

  

Ergo the name. The last step of the
puzzle is to make 'authenticating' (ie: checking the password) optional
in your realm. I coded my LoginModule to have a flag checkPassword="false".

I know that's not the whole picture but it's the gist of it to get a
discussion going. What do people here think, am I following a logical
path or have I completely jumped the shark?



Why not work with the code that the redirector uses to set the Principal
in the first place? I think it would be a cleaner implementation to set
the roles at the time the Principal object is created.

- -chris

Thanks Chris for the detailed response.

I'll have to go back and review how the IIS isapi_redirector.dll is 
hooked into Tomcat to see if changing the redirector would better suit 
my needs.


The reason why I went with this style implementation: it was the first 
way I've figured out of implementing my requirements and it worked. (ie: 
not a good reason architecturally, it just worked). One argument in 
favour of this style of implementation is that it can work with other 
external redirector implementations that embed a Principal in the Request.


I'm not sure about your question re: Is it doing any authorization? My 
understanding of JAAS is that the binding of Roles to the Principal was 
the Authorization. Doing this does allows the security declarations in 
the web.xml to work as expected. ie: The container (tomcat/jboss/etc.) 
is doing the work of checking if the user is in the role.


Yes it is time consuming to do bind the roles on every request. I'm not 
sure yet how the redirector binds the Principal to the Request (per 
session or per request) and/or how Roles are normally bound to the 
Principal.
I'll have to go back to the Tomcat source and trace what's happening in 
the Realm source.


I don't have the experience or tools to be able to create an updated 
redirector. I'm trying to make an implementation that isn't specific to 
the IIS redirector and could be used with other types of redirectors. 
Also, I'm trying to keep my implementation 'java' and I don't know what 
the redirector .dll is written in.


I see where you're going with your suggestions. If the Principal from 
the redirector is created once and the same one is used across requests 
(in a session) then it should be trivial to mutate it (by binding the 
roles in) instead of substituting it with a new one with the roles bound in.


Thanks for taking the time to write a detailed response. I'll get back 
to the list with my changes when I've got them done.


Best Regards,

Louis

---

Re: TrustedPrincipalAuthorizor (extends AuthenticatorBase) Discussion / Comments

2007-12-22 Thread Christopher Schultz
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Louis,

Louis wrote:
> When trying to decide which Authentication I should use I reviewed the
> source for the existing ones and realized that none of them would work.
> The existing authenticators all check to see if a principal is already
> in the request. If it is then the user has already been authenticated
> and the authenticator never goes to the Realm to see what permissions /
> roles the user has.

That's not how it's supposed to work; authentication and authorization
are separate. Without looking at the source (don't have it handy right
now), the flow ought to be:

- - Determine authentication and authorization requirements
  based upon request URL
- - Check request for principal
  |- if not found, check request for credentials
  |   - if found, load principal into request
  |   - if not found, display login challenge and exit
- - Use found principal for authorization (check roles)

Tomcat's built-in Principal and Request objects conspire to correctly
wire HttpServletRequest.isUserInRole to something within the Principal.
If you choose to gather your Principal information from somewhere else
(NTLM), then you need to take care to play along with Tomcat's notion of
where roles are stored.

If Tomcat does not use the HttpServletRequest.isUserInRole method to
perform its authorization, then you will need to pay attention to the
way it /does/ check for the roles.

> Since the IIS connector plugs-in a Principal for the
> user, this effectively short-circuited the ability of the container to
> bind roles to the user.

You should be able to wrap that Principal in some other object if necessary.

> My solution was to code my own TrustedPrincipalAuthorizor (extends
> AuthenticatorBase). I called it an authorizor since it wasn't doing any
> actual Authentication.

Is it doing any authorization, or is it just attaching roles to a
Principal and allowing Tomcat to perform the authorization?

> This class checks for the existence of a
> principal in the request. It then uses that principal as the key to tell
> the security realm to lookup the users permissions and bind them into
> the container for this request.

That seems a little time-consuming to do for every request. Since you're
working with Tomcat's internals, why not permanently attach the role
information to the Principal object one time?

> Ergo the name. The last step of the
> puzzle is to make 'authenticating' (ie: checking the password) optional
> in your realm. I coded my LoginModule to have a flag checkPassword="false".
> 
> I know that's not the whole picture but it's the gist of it to get a
> discussion going. What do people here think, am I following a logical
> path or have I completely jumped the shark?

Why not work with the code that the redirector uses to set the Principal
in the first place? I think it would be a cleaner implementation to set
the roles at the time the Principal object is created.

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

iEYEARECAAYFAkdt67EACgkQ9CaO5/Lv0PCxWgCfTrpnpbtbocP5XFna6akX9hNM
UIIAoJwGgxGIL/wkVscAeh47g2rjk2RQ
=simi
-END PGP SIGNATURE-

-
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



TrustedPrincipalAuthorizor (extends AuthenticatorBase) Discussion / Comments

2007-12-21 Thread Louis
Hi, I'm new to the list though I've been developing on Tomcat and JBoss 
for a few years now. Presented below are two classes I'd like feedback 
on. Anything is appreciated but I'm hoping for feedback mostly on the 
ideas behind the implementation more than particular bug fixes (that can 
come if I'm on the right track).


Also, I've introduced this to the users list first in case I've gone 
astray and there's a better way to do this elsewhere.


## Boring Backstory ## (This rambles for a bit. You can skip to the 
juicy bit by scrolling down to # Implementation Details #)


My background is primarily struts/hibernate based development. In that 
time I've had a few chances to write LoginModules (Similar to custom 
Realm in Tomcat) for a couple of different needs.


I recently joined a team that was using the IIS isapi_redirector.dll for 
tomcat to do transparent authentication. This is great for the end user. 
However a problem the team was having is that they're still doing 
programmatic security for everything. Why? The IIS connector connects to 
Tomcat and embeds a Principal with the users Windows Domain / Username 
in it. The team simply took this and then manually checked the users 
permissions for each operation. Yes there's a time and a place for 
programmatic security, but if you can let the container manage security 
why not? (Note: This is all being done for a MS Windows Corporate 
Intranet which is why the use of NTLM is accepted)


It was trivial to write a JBoss Login Module for their existing security 
database. However, I came across a problem when getting the 
authentication to happen: Tomcat wasn't authenticating the users. This 
makes sense since I hadn't told Tomcat to do any authentication in the 
WEB.XML file.


When trying to decide which Authentication I should use I reviewed the 
source for the existing ones and realized that none of them would work. 
The existing authenticators all check to see if a principal is already 
in the request. If it is then the user has already been authenticated 
and the authenticator never goes to the Realm to see what permissions / 
roles the user has. Since the IIS connector plugs-in a Principal for the 
user, this effectively short-circuited the ability of the container to 
bind roles to the user.


My solution was to code my own TrustedPrincipalAuthorizor (extends 
AuthenticatorBase). I called it an authorizor since it wasn't doing any 
actual Authentication. This class checks for the existence of a 
principal in the request. It then uses that principal as the key to tell 
the security realm to lookup the users permissions and bind them into 
the container for this request. Ergo the name. The last step of the 
puzzle is to make 'authenticating' (ie: checking the password) optional 
in your realm. I coded my LoginModule to have a flag checkPassword="false".


I know that's not the whole picture but it's the gist of it to get a 
discussion going. What do people here think, am I following a logical 
path or have I completely jumped the shark?


TrustedPrincipalAuthorizor.java

This allows me to force authentication to continue on to the realms in 
order to populate the user's request with their roles. (IE: use the full 
power of container managed security).


ContextLookupAuthenticatorBase.java

This came about because: 1. JBoss 3.2.5 doesn't support the  
element or a context.xml file from tomcat to be able to make deployment 
changes to a program.
2. After studying the AuthenticatorBase I determined that it didn't 
actually _need_ to be hosted inside of a context element. It can get the 
context from the request, so it can determine dynamically which context 
and realm apply to the request.


This was desireable since we use this function across all our intranet 
applications and didn't want to have to declare it again for each app. 
This is actually fairly redundant and I (at present) don't see why the 
AuthenticatorBase must be implmented to be context dependant. (I can see 
why it is, just not the architectural reason why it _must be_).



## Implementation Details ##

Here's the rough source for my TrustedPrincipalAuthorizor.

The java files can be downloaded from:
http://www.laj.ca/source/tomcat/TrustedPrincipalAuthorizor.java
http://www.laj.ca/source/tomcat/ContextLookupAuthenticatorBase.java

/*
* Copyright 2007 Louis A. J. Pierrson
* based on code
* Copyright 1999-2001,2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*

TrustedPrincipalAuthorizor (extends AuthenticatorBase) Discussion / Comments

2007-12-21 Thread Louis
Hi, I'm new to the list though I've been developing on Tomcat and JBoss 
for a few years now. Presented below are two classes I'd like feedback 
on. Anything is appreciated but I'm hoping for feedback mostly on the 
ideas behind the implementation more than particular bug fixes (that can 
come if I'm on the right track).


Also, I've introduced this to the users list first in case I've gone 
astray and there's a better way to do this elsewhere.


## Boring Backstory ## (This rambles for a bit. You can skip to the 
juicy bit by scrolling down to # Implementation Details #)


My background is primarily struts/hibernate based development. In that 
time I've had a few chances to write LoginModules (Similar to custom 
Realm in Tomcat) for a couple of different needs.


I recently joined a team that was using the IIS isapi_redirector.dll for 
tomcat to do transparent authentication. This is great for the end user. 
However a problem the team was having is that they're still doing 
programmatic security for everything. Why? The IIS connector connects to 
Tomcat and embeds a Principal with the users Windows Domain / Username 
in it. The team simply took this and then manually checked the users 
permissions for each operation. Yes there's a time and a place for 
programmatic security, but if you can let the container manage security 
why not? (Note: This is all being done for a MS Windows Corporate 
Intranet which is why the use of NTLM is accepted)


It was trivial to write a JBoss Login Module for their existing security 
database. However, I came across a problem when getting the 
authentication to happen: Tomcat wasn't authenticating the users. This 
makes sense since I hadn't told Tomcat to do any authentication in the 
WEB.XML file.


When trying to decide which Authentication I should use I reviewed the 
source for the existing ones and realized that none of them would work. 
The existing authenticators all check to see if a principal is already 
in the request. If it is then the user has already been authenticated 
and the authenticator never goes to the Realm to see what permissions / 
roles the user has. Since the IIS connector plugs-in a Principal for the 
user, this effectively short-circuited the ability of the container to 
bind roles to the user.


My solution was to code my own TrustedPrincipalAuthorizor (extends 
AuthenticatorBase). I called it an authorizor since it wasn't doing any 
actual Authentication. This class checks for the existence of a 
principal in the request. It then uses that principal as the key to tell 
the security realm to lookup the users permissions and bind them into 
the container for this request. Ergo the name. The last step of the 
puzzle is to make 'authenticating' (ie: checking the password) optional 
in your realm. I coded my LoginModule to have a flag checkPassword="false".


I know that's not the whole picture but it's the gist of it to get a 
discussion going. What do people here think, am I following a logical 
path or have I completely jumped the shark?


TrustedPrincipalAuthorizor.java

This allows me to force authentication to continue on to the realms in 
order to populate the user's request with their roles. (IE: use the full 
power of container managed security).


ContextLookupAuthenticatorBase.java

This came about because: 1. JBoss 3.2.5 doesn't support the  
element or a context.xml file from tomcat to be able to make deployment 
changes to a program.
2. After studying the AuthenticatorBase I determined that it didn't 
actually _need_ to be hosted inside of a context element. It can get the 
context from the request, so it can determine dynamically which context 
and realm apply to the request.


This was desireable since we use this function across all our intranet 
applications and didn't want to have to declare it again for each app. 
This is actually fairly redundant and I (at present) don't see why the 
AuthenticatorBase must be implmented to be context dependant. (I can see 
why it is, just not the architectural reason why it _must be_).



## Implementation Details ##

Here's the rough source for my TrustedPrincipalAuthorizor.

The java files can be downloaded from:
http://www.laj.ca/source/tomcat/TrustedPrincipalAuthorizor.java
http://www.laj.ca/source/tomcat/ContextLookupAuthenticatorBase.java

/*
* Copyright 2007 Louis A. J. Pierrson
* based on code
* Copyright 1999-2001,2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*