geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Jencks <david_jen...@yahoo.com>
Subject Proposed Security changes for run-as and default subjects.
Date Tue, 05 Jun 2007 22:38:01 GMT
I've discussed this at least once before, see also GERONIMO-2687.

I've been working on this idea of having all run-as and default  
subjects be from login modules/configurations rather than the current  
plan of constructing subjects from confusing xml.  It seems to be  
working pretty well and I'm at the point where I would like to commit  
it so I'd like to find out if there are any objections to the non- 
backward-compatible aspects of the changes.

The core of the idea is an interface

public interface CredentialStore {
     Subject getSubject(String realm, String id) throws LoginException;
}

that lets the servlet and ejb containers obtain a subject given an  
identifier.

The CredentialStore I've implemented is currently configured with xml  
like this:

     <gbean name="CredentialStore"  
class="org.apache.geronimo.security.credentialstore.SimpleCredentialStor 
eImpl">
         <xml-attribute name="credentialStore">
             <credential-store xmlns="http://geronimo.apache.org/xml/ 
ns/credentialstore-1.0">
                 <realm name="my-realm">
                     <subject>
                         <id>foo-run-as</id>
                         <credential>
                              
<type>org.apache.geronimo.security.credentialstore.NameCallbackHandler</ 
type>
                             <value>foo</value>
                         </credential>
                         <credential>
                              
<type>org.apache.geronimo.security.credentialstore.PasswordCallbackHandl 
er</type>
                             <value>fooPassword</value>
                         </credential>
                     </subject>
                     <subject>
                         <id>bar-run-as</id>
                         <credential>
                              
<type>org.apache.geronimo.security.credentialstore.NameCallbackHandler</ 
type>
                             <value>bar</value>
                         </credential>
                         <credential>
                              
<type>org.apache.geronimo.security.credentialstore.PasswordCallbackHandl 
er</type>
                             <value>barPassword</value>
                         </credential>
                     </subject>
                 </realm>
             </credential-store>
         </xml-attribute>
     </gbean>


Note that this has cleartext passwords in it.  It's a plan so after  
deployment there's no textual representation of it in the car file.   
This is obviously a poor feature and I'd certainly like suggestions  
for improvement.  One possibility is to put the configuration in a  
file which can then be encrypted.  However, it's difficult for me to  
figure out a solution that's really secure rather than just obfuscation.

The plan xml security configuration element now looks like this:

       <security use-context-handler="false">
         <default-subject>
             <realm>my-realm</realm>
             <id>bar-run-as</id>
         </default-subject>
         <role-mappings>
           <role role-name="Administrator">
             <realm realm-name="my-realm">
               <principal  
class="org.apache.geronimo.security.realm.providers.GeronimoUserPrincipa 
l" name="bar"/>
             </realm>
           </role>
           <role role-name="Manager">
             <subject-info>
                 <realm>my-realm</realm>
                 <id>foo-run-as</id>
	    </subject-info>
             <realm realm-name="my-realm">
               <principal  
class="org.apache.geronimo.security.realm.providers.GeronimoUserPrincipa 
l" name="foo"/>
             </realm>
           </role>
         </role-mappings>
       </security>

This sets the default subject to bar and the run-as subject for the  
Manager role to foo.


--------------------------
Comparison with current model/xml.

Currently there is nothing like the credential store configuration  
and the run-as subjects are constructed from xml like this:

       <security use-context-handler="false">
         <default-principal realm-name="cts-properties-realm">
           <principal  
class="org.apache.geronimo.security.realm.providers.GeronimoUserPrincipa 
l" name="j2ee"/>
         </default-principal>
         <role-mappings>
           <role role-name="Administrator">
             <realm realm-name="my-realm">
               <principal  
class="org.apache.geronimo.security.realm.providers.GeronimoUserPrincipa 
l" name="bar"/>
             </realm>
           </role>
           <role role-name="Manager">
             <realm realm-name="my-realm">
               <principal  
class="org.apache.geronimo.security.realm.providers.GeronimoUserPrincipa 
l" name="foo" designated-run-as="true"/>
             </realm>
           </role>
         </role-mappings>
       </security>

This is somewhat limiting and I've always found it almost impossible  
to understand:
Since all authorization flows from a Subject not a Principal, the  
concept of default-principal is kind of ridiculous on its face.   
Replacing it with a default subject allows you to configure the  
default authorization with whatever detail you want.
Along with the odd practice of constructing a Subject  without using  
a login module, this style of configuration can be a bit confusing.   
Consider this configuration example:
       <security use-context-handler="false">
         <role-mappings>
           <role role-name="Administrator">
             <realm realm-name="my-realm">
               <principal  
class="org.apache.geronimo.security.realm.providers.GeronimoUserPrincipa 
l" name="bar" designated-run-as="true"/>
               <principal  
class="org.apache.geronimo.security.realm.providers.GeronimoUserPrincipa 
l" name="foo"/>
             </realm>
           </role>
           <role role-name="Manager">
             <realm realm-name="my-realm">
               <principal  
class="org.apache.geronimo.security.realm.providers.GeronimoUserPrincipa 
l" name="foo" designated-run-as="true"/>
             </realm>
           </role>
         </role-mappings>
       </security>

One of the effects of this configuration is that run-as="Manager"  
also gets the "Administrator" role, whereas run-as="Administrator"  
only gets the "Administrator" role.  I find this very hard to  
interpret correctly in practice.  The same kind of effect can occur  
in the configuration I'm proposing, but I think it will be a lot more  
obvious: you are picking a particular user in a particular login  
realm and it's pretty clear that to find out what roles/permissions  
that user has you have to look at all the principals involved and  
trace them into the principals>>role>> permission mapping.

------------------------
Backward compatibility state:

I don't see any reasonable way to convert the previous configuration  
to work exactly the same way with the new model.  At the moment I've  
set up the xml plan processing to delete/ignore default-principal and  
designated-run-as elements/attributes, but not try to reinterpret  
them to something in the new system.  So you should still be able to  
deploy with an old plan, but the default identity and run as aspects  
won't work as expected.

------------------------
Next steps:

-- figure out how to at least obfuscate the credentials in the  
credential store configuration
-- figure out how to dynamically manage the contents of the  
credential store
-- Our principal>> role mapping is extremely flexible but may often  
be waaaaay more complicated than necessary.  Furthermore it's just  
possible that some people will want to have run-as-role mean exactly  
what it seems, without any other further configuration or  
flexibility.  Both these concerns could be addressed by making it  
possible to have a principal name == role name mapping.

One possible configuration might look like this:
         <role-mappings>
           <auto-map>
             <realm realm-name="my-realm">
               <principal  
class="org.apache.geronimo.security.realm.providers.GeronimoGroupPrincip 
al"/>
               <principal  
class="org.apache.geronimo.security.realm.providers.GeronimoUserPrincipa 
l"/>
             </realm>
             <run-as-realm>run-as-realm</run-as-realm>
           </auto-map>
         </role-mappings>

The <realm> element contains principals for which you want a  
principal-name = role-name mapping.
The run-as-realm would set up a realm that requires no credentials,  
just a (role) name and produce a subject with a single (role)  
principal mapped to that role.

-- I don't think that including the realm in subject-info is strictly  
necessary but at this point I think it will lead to less confusion  
and possible overlap, so I'm inclined to keep it.  If anyone strongly  
objects it's not hard to remove.


-------------------------------
Please comment.  Since this is a backward-incompatible change I would  
like to get it in quickly and definitely before 2.0 goes out the  
door.  I'm hoping that few enough people have ever used run-as that  
it won't be a major burden on existing users.

thanks
david jencks



Mime
View raw message