Re: TrustedPrincipalAuthorizor (extends AuthenticatorBase) Discussion / Comments
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
-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
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
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. *