|
View:
New views
6 Messages
—
Rating Filter:
Alert me
|
|
|
example config for using CAS for SSO with RollerHi all, I've recently spent some time getting Roller to work in an SSO
environment with CAS and thought I'd share my config and code with the group in case anybody else is trying to do this. But before the config files and code, a couple of notes: First: if you want to get Roller working with CAS, I *highly* recommend working through the Acegi tutorials, and get the minimal sample app working with CAS in your environment first. Also read over the CAS docs and understand how to build and deploy CAS, including configuring custom plugins. Trust me, having some understanding of what's going on will help a lot. Second: what's required for Roller to work with CAS is almost exclusively configuration in security.xml. I added one class to my Roller build, which is basically just a stub implementation of a CasAuthoritiesPopulator, because one of the Acegi classes expects to be injected with one of those. My implementation doesn't actually do anything though, except pass through the object returned by the UserDetailsService. Third: this config is *not* perfect. It was done using some copy and paste from the Acegi tutorial app and was adapted and tweaked until it worked. So there's probably left over cruft in there that's not even necessary. Also I temporarily took out the "remember me" stuff to simplify things until I got the base functionality working. But while not perfect, in my preliminary testing it does work as intended. If anybody tries this and runs into problems, please post back to this list and I'll help if I can. Ok, finally, there should be two attachments. One is my security.xml. You should be able to replace your security.xml with this, tweak a few Urls and be close to good to go. I think you'll also need to find the cas client jar file and add it to your WEB-INF/lib. Also, if you don't have SSL enabled for your app server, you'll need to do that. CAS assumes the availability of SSL. The other attachment is my users.RollerPopulator class, which is the aforementioned stub implementation of CasAuthoritiesPopulator. There may be a way to avoid needing this, but I haven't dug into things deeply enough yet to be sure. HTH, YMMV, IANAL, etc. Phil <?xml version="1.0" encoding="UTF-8"?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. The ASF licenses this file to You 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. For additional information regarding copyright in this work, please see the NOTICE file in the top level directory of this distribution. --> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!-- ======================== FILTER CHAIN ======================= --> <bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy"> <property name="filterInvocationDefinitionSource"> <value> CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON PATTERN_TYPE_APACHE_ANT /**=channelProcessingFilter,httpSessionContextIntegrationFilter,logoutFilter,casProcessingFilter,basicProcessingFilter,securityContextHolderAwareRequestFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor </value> </property> </bean> <!-- ===================== HTTP CHANNEL REQUIREMENTS ==================== --> <!-- Enabled by default for CAS, as a CAS deployment uses HTTPS --> <bean id="channelProcessingFilter" class="org.acegisecurity.securechannel.ChannelProcessingFilter"> <property name="channelDecisionManager"> <ref local="channelDecisionManager"/> </property> <property name="filterInvocationDefinitionSource"> <value> CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON \A/j_acegi_cas_security_check.*\Z=REQUIRES_SECURE_CHANNEL \A.*\Z=REQUIRES_INSECURE_CHANNEL </value> </property> </bean> <bean id="channelDecisionManager" class="org.acegisecurity.securechannel.ChannelDecisionManagerImpl"> <property name="channelProcessors"> <list> <ref local="secureChannelProcessor"/> <ref local="insecureChannelProcessor"/> </list> </property> </bean> <bean id="secureChannelProcessor" class="org.acegisecurity.securechannel.SecureChannelProcessor"/> <bean id="insecureChannelProcessor" class="org.acegisecurity.securechannel.InsecureChannelProcessor"/> <!-- ======================== HTTP SESSION CONTEXT INTEGRATION ======================= --> <bean id="httpSessionContextIntegrationFilter" class="org.acegisecurity.context.HttpSessionContextIntegrationFilter"/> <!-- ======================== LOGOUT ======================= --> <!-- note logout has little impact, due to CAS reauthentication functionality (it will cause a refresh of the authentication though) --> <bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter"> <constructor-arg value="/index.jsp"/> <!-- URL redirected to after logout --> <constructor-arg> <list> <bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/> </list> </constructor-arg> </bean> <!-- ======================== CENTRAL AUTHENTICATION SERVICE (CAS) ======================= --> <bean id="casProcessingFilter" class="org.acegisecurity.ui.cas.CasProcessingFilter"> <property name="authenticationManager"> <ref local="authenticationManager"/> </property> <property name="authenticationFailureUrl"> <value>/casfailed.jsp</value> </property> <property name="defaultTargetUrl"> <value>/</value> </property> <property name="filterProcessesUrl"> <value>/j_acegi_cas_security_check</value> </property> </bean> <!-- ***NOTE*** change the loginUrl below to the correct value for your environment --> <bean id="casProcessingFilterEntryPoint" class="org.acegisecurity.ui.cas.CasProcessingFilterEntryPoint"> <property name="loginUrl"><value>https://localhost:8443/cas/login</value></property> <property name="serviceProperties"><ref local="serviceProperties"/></property> </bean> <bean id="casAuthenticationProvider" class="org.acegisecurity.providers.cas.CasAuthenticationProvider"> <property name="casAuthoritiesPopulator"> <ref local="casAuthoritiesPopulator"/> </property> <property name="casProxyDecider"><ref local="casProxyDecider"/></property> <property name="ticketValidator"><ref local="casProxyTicketValidator"/></property> <property name="statelessTicketCache"><ref local="statelessTicketCache"/></property> <property name="key"><value>my_password_for_this_auth_provider_only</value></property> </bean> <!-- ***NOTE*** change the Urls below to the correct value for your environment --> <bean id="casProxyTicketValidator" class="org.acegisecurity.providers.cas.ticketvalidator.CasProxyTicketValidator"> <property name="casValidate"><value>https://localhost:8443/cas/proxyValidate</value></property> <property name="proxyCallbackUrl"><value>https://localhost:8443/Roller31/casProxy/receptor</value></property> <property name="serviceProperties"><ref local="serviceProperties"/></property> <!-- <property name="trustStore"><value>/some/path/to/your/lib/security/cacerts</value></property> --> </bean> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/> <bean id="ticketCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> <property name="cacheManager"> <ref local="cacheManager"/> </property> <property name="cacheName"> <value>ticketCache</value> </property> </bean> <bean id="statelessTicketCache" class="org.acegisecurity.providers.cas.cache.EhCacheBasedTicketCache"> <property name="cache"><ref local="ticketCacheBackend"/></property> </bean> <!-- ***NOTE*** the class RollerPopulator doesn't really do anything, but pass through the user object obtained from the UserDetailsService. A more complicated environment might require a class to do some lookups to another database or service to determine GrantedAuthoritys for the user object. That's not necessary here since the jdbcAuthenticationDao gives us everything we need --> <bean id="casAuthoritiesPopulator" class="users.RollerPopulator"> <property name="userDetailsService"> <ref local="jdbcAuthenticationDao" /> </property> </bean> <bean id="casProxyDecider" class="org.acegisecurity.providers.cas.proxy.RejectProxyTickets"> </bean> <!-- ***NOTE*** set the url below to the correct value for your environment --> <bean id="serviceProperties" class="org.acegisecurity.ui.cas.ServiceProperties"> <property name="service"><value>https://localhost:8443/Roller31/j_acegi_cas_security_check</value></property> <property name="sendRenew"><value>false</value></property> </bean> <!-- ======================== BASIC PROCESSING ======================= --> <bean id="basicProcessingFilter" class="org.acegisecurity.ui.basicauth.BasicProcessingFilter"> <property name="authenticationManager"> <ref local="authenticationManager"/> </property> <property name="authenticationEntryPoint"> <ref local="basicProcessingFilterEntryPoint"/> </property> </bean> <bean id="basicProcessingFilterEntryPoint" class="org.acegisecurity.ui.basicauth.BasicProcessingFilterEntryPoint"> <property name="realmName"><value>Contacts Realm</value></property> </bean> <!-- ======================== SECURITY CONTEXT HOLDER AWARE ======================= --> <bean id="securityContextHolderAwareRequestFilter" class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter"/> <!-- ======================== ANONYMOUS PROCESSING ======================= --> <bean id="anonymousProcessingFilter" class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter"> <property name="key" value="anonymous"/> <property name="userAttribute" value="anonymous,ROLE_ANONYMOUS"/> </bean> <bean id="anonymousAuthenticationProvider" class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider"> <property name="key" value="anonymous"/> </bean> <!-- ======================== EXCEPTION TRANSLATION ======================= --> <bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter"> <property name="authenticationEntryPoint"> <ref local="casProcessingFilterEntryPoint"/> </property> <property name="accessDeniedHandler"> <bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl"> <property name="errorPage" value="/accessDenied.jsp"/> </bean> </property> </bean> <!-- ======================== FILTER INVOCATION INTERCEPTOR ======================= --> <!-- Note the order that entries are placed against the objectDefinitionSource is critical. The FilterSecurityInterceptor will work from the top of the list down to the FIRST pattern that matches the request URL. Accordingly, you should place MOST SPECIFIC (ie a/b/c/d.*) expressions first, with LEAST SPECIFIC (ie a/.*) expressions last --> <bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor"> <property name="authenticationManager"><ref local="authenticationManager"/></property> <property name="accessDecisionManager"><ref local="accessDecisionManager"/></property> <property name="objectDefinitionSource"> <value> PATTERN_TYPE_APACHE_ANT /roller-ui/login-redirect.jsp=admin,editor /roller-ui/yourProfile**=admin,editor /roller-ui/createWebsite**=admin,editor /roller-ui/yourWebsites**=admin,editor /roller-ui/authoring/**=admin,editor /roller-ui/admin/**=admin /rewrite-status*=admin </value> </property> </bean> <!-- CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON (apparently we can't use this because the URLs have things like yourProfile which has uppercase init --> <!-- ======================== AUTHENTICATION ======================= --> <!-- Read users from database --> <bean id="jdbcAuthenticationDao" class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl"> <property name="dataSource"> <bean class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="java:comp/env/jdbc/rollerdb"/> </bean> </property> <property name="usersByUsernameQuery"> <value>SELECT username,passphrase,isenabled FROM rolleruser WHERE username = ?</value> </property> <property name="authoritiesByUsernameQuery"> <value>SELECT username,rolename FROM userrole WHERE username = ?</value> </property> </bean> <!-- ======================== AUTHENTICATION ======================= --> <bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager"> <property name="providers"> <list> <ref local="casAuthenticationProvider"/> <ref local="anonymousAuthenticationProvider"/> </list> </property> </bean> <!-- ===================== HTTP REQUEST SECURITY ==================== --> <bean id="accessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased"> <property name="allowIfAllAbstainDecisions"> <value>false</value> </property> <property name="decisionVoters"> <list> <ref bean="roleVoter"/> </list> </property> </bean> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames"> <list> <value>classpath:/org/acegisecurity/messages</value> </list> </property> </bean> <!-- ~~~~~~~~~~~~~~~~~~ AUTHORIZATION VOTER ~~~~~~~~~~~~~~~~ --> <!-- An access decision voter --> <bean id="roleVoter" class="org.acegisecurity.vote.RoleVoter"> <property name="rolePrefix" value=""/> </bean> <!-- ~~~~~~~~~~~~~~~~~~ "BEFORE INVOCATION" AUTHORIZATION DEFINITIONS ~~~~~~~~~~~~~~~~ --> <!-- ACL permission masks used by this application --> <bean id="org.acegisecurity.acls.domain.BasePermission.ADMINISTRATION" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"> <property name="staticField"><value>org.acegisecurity.acls.domain.BasePermission.ADMINISTRATION</value></property> </bean> <bean id="org.acegisecurity.acls.domain.BasePermission.READ" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"> <property name="staticField"><value>org.acegisecurity.acls.domain.BasePermission.READ</value></property> </bean> <bean id="org.acegisecurity.acls.domain.BasePermission.DELETE" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"> <property name="staticField"><value>org.acegisecurity.acls.domain.BasePermission.DELETE</value></property> </bean> <!-- ~~~~~~~~~~~~~~~~~~ LOGGER ~~~~~~~~~~~~~~~~ --> <!-- This bean is optional; it isn't used by any other bean as it only listens and logs --> <bean id="loggerListener" class="org.acegisecurity.event.authentication.LoggerListener"/> <!-- ################################### WORRY ABOUT THIS STUFF LATER #############################################--> <!-- ===================== REMEMBER ME ==================== --> <!-- <bean id="rememberMeProcessingFilter" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter"> <property name="authenticationManager" ref="authenticationManager"/> <property name="rememberMeServices" ref="rememberMeServices"/> </bean> <bean id="rememberMeServices" class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices"> <property name="userDetailsService" ref="jdbcAuthenticationDao"/> <property name="key" value="rollerlovesacegi"/> <property name="parameter" value="rememberMe"/> </bean> <bean id="rememberMeAuthenticationProvider" class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider"> <property name="key" value="rollerlovesacegi"/> </bean> --> </beans> package users; import org.acegisecurity.AuthenticationException; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.providers.cas.CasAuthoritiesPopulator; import org.acegisecurity.userdetails.User; import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UserDetailsService; import org.apache.log4j.Logger; public class RollerPopulator implements CasAuthoritiesPopulator { private static final Logger logger = Logger.getLogger( RollerPopulator.class ); private UserDetailsService userDetailsService; public UserDetailsService getUserDetailsService() { return userDetailsService; } public void setUserDetailsService( UserDetailsService userDetailsService ) { this.userDetailsService = userDetailsService; } public UserDetails getUserDetails( String userName ) throws AuthenticationException { logger.info( "RollerPopulator.getUserDetails() called!" ); User userObject = (User)userDetailsService.loadUserByUsername( userName ); // in a more sophisticated implementation we would look up and insert // GrantedAuthoritys here. return( userObject ); } } |
|
|
Re: example config for using CAS for SSO with RollerA few extra note and points of clarification... anybody who's
trying to implement SSO probably already understands these issues (or at least these kinds of issues) but just in case it will help somebody: This configuration still uses the same roller database tables and information for authorization. That is, after a user is authenticated using CAS, the code will try to look that username up in the roller db, in order to set the authorities for the user. Additionally, I imagine the Roller code - at some level - expects entries in whichever table it uses for user information so it can maintain associations between a given user and their blog, etc. This is important because it implies (in the most common scenario) that a user has to be provisioned in TWO databases - whatever CAS is authenticating against, and the Roller DB - before they can use the system. There are a couple of ways to mitigate the impact of this. First, if you wanted too you could have CAS authenticate against the Roller DB. If you want Roller to be the canonical source of authentication information for your entire SSO environment, that's fine. I doubt most people will want that though. So, assuming CAS is authenticating against some other database (maybe the organization's LDAP server or Active Directory or something) you have a couple of options. IF you can get the appropriate authorization information put into that canonical database, then you can point the UserDetailsService at that and only maintain users in one place, at least as far as authentication and authorization go. Even then I think it'll turn out that entries still have to be populated into Roller's user table(s) for maintaining associations. The positive about this scenario is that you can probably automate the process of populating the roller table. Eg, "here's a new user that's authenticated but we don't have a user record for, so let's create this user in our db" on the Roller side. A more elegant solution would be to automatically provision / deprovision the user across all systems in response to their creation in the canonical identity database. Doing this can obviously get complicated, but the basic idea would be to have something like a database trigger, or a hook point provided by the identity system, send a message to all the systems in the SSO environment saying "Hey, user JoeBob has been created, create this guy in your own database" or "Hey, user JoeBob has been deleted, get rid of your records for him." Implementing this is left as an exercise for the reader. :-) TTYL, Phil |
|
|
Re: example config for using CAS for SSO with RollerOn 8/11/07, Phillip Rhodes <mindcrime@...> wrote:
> A few extra note and points of clarification... anybody who's > trying to implement SSO probably already understands these > issues (or at least these kinds of issues) but just in case it > will help somebody: Thanks for posting these notes Phillip. > This configuration still uses the same roller database tables > and information for authorization. That is, after a user is > authenticated using CAS, the code will try to look that username > up in the roller db, in order to set the authorities for the > user. Additionally, I imagine the Roller code - at some level - expects > entries in whichever table it uses for user information so it can > maintain associations between a given user and their blog, etc. I hope to be breaking some of those associations in 4.1 and make it possible to externalize Roller's user and permissions management. Check the proposal here: http://cwiki.apache.org/confluence/display/ROLLER/Proposal+Externalize+User+And+Permissions+Management - Dave |
|
|
Re: example config for using CAS for SSO with RollerI'm trying these instructions and I've gotten as far as configuring
security.xml and getting Roller started. In addition to these instructions, I had to add casclient.jar to my WEB-INF/lib directory. Do you know how I can add users to CAS or how to have it read users from LDAP? Thanks, Matt On 8/11/07, Phillip Rhodes <mindcrime@...> wrote: > A few extra note and points of clarification... anybody who's > trying to implement SSO probably already understands these > issues (or at least these kinds of issues) but just in case it > will help somebody: > > This configuration still uses the same roller database tables > and information for authorization. That is, after a user is > authenticated using CAS, the code will try to look that username > up in the roller db, in order to set the authorities for the > user. Additionally, I imagine the Roller code - at some level - expects > entries in whichever table it uses for user information so it can > maintain associations between a given user and their blog, etc. > > This is important because it implies (in the most common scenario) > that a user has to be provisioned in TWO databases - whatever CAS is > authenticating against, and the Roller DB - before they can use > the system. > > There are a couple of ways to mitigate the impact of this. First, if > you wanted too you could have CAS authenticate against the Roller DB. > If you want Roller to be the canonical source of authentication > information for your entire SSO environment, that's fine. I doubt most > people will want that though. > > So, assuming CAS is authenticating against some other database (maybe > the organization's LDAP server or Active Directory or something) you > have a couple of options. > > IF you can get the appropriate authorization information put into that > canonical database, then you can point the UserDetailsService at that > and only maintain users in one place, at least as far as authentication > and authorization go. Even then I think it'll turn out that entries > still have to be populated into Roller's user table(s) for maintaining > associations. The positive about this scenario is that you can probably > automate the process of populating the roller table. Eg, "here's a new > user that's authenticated but we don't have a user record for, so let's > create this user in our db" on the Roller side. > > A more elegant solution would be to automatically provision / > deprovision the user across all systems in response to their creation in > the canonical identity database. Doing this can obviously get > complicated, but the basic idea would be to have something like > a database trigger, or a hook point provided by the identity > system, send a message to all the systems in the SSO environment > saying "Hey, user JoeBob has been created, create this guy > in your own database" or "Hey, user JoeBob has been deleted, get rid > of your records for him." Implementing this is left as an exercise > for the reader. :-) > > > > TTYL, > > > Phil > -- http://raibledesigns.com |
|
|
Re: example config for using CAS for SSO with RollerMatt Raible wrote:
> I'm trying these instructions and I've gotten as far as configuring > security.xml and getting Roller started. In addition to these instructions, > I had to add casclient.jar to my WEB-INF/lib directory. > > Do you know how I can add users to CAS or how to have it read users from > LDAP? Automatically provisioning users to both CAS and Roller will take some custom coding if you approach it the way I did. For the system I'm working on, I wrote a simple "User Registration App" that handles all user registration and provisioning and writes the necessary records to three databases: CAS, Roller and JavaBB; and wrote a new CAS authentication module to use my "CAS User" database. This keeps CAS and it's associated database as the canonical authentication db for the entire system. Strictly speaking it's not *necessary* to have three databases, as I could have written a CAS authentication module with the "knowledge" to use either the existing Roller db or JavaBB db, but I went that direction because it is more consistent with my long-term aims. But if you just "point" CAS at the roller db, then you avoid the issue of needing to provision users to extra places. But now you've made Roller the canonical system for authentication for the entire SSO domain, which may or may not be appropriate. As for getting CAS to read from LDAP, I'm not sure as I haven't tried that. If there is an existing CAS authentication module for LDAP then it should just be a case of configuring CAS appropriately. But that might be a question better asked on the CAS list. If there isn't an existing module for that, it would mean writing a new CAS authentication module. That's not hard to do, luckily. I wrote a simple one for the project I'm working on. If anybody is interested in seeing it as an example, I'll be happy to post the code. Thanks, Phil |
|
|
Re: example config for using CAS for SSO with RollerHi Matt,
you could try org.acegisecurity.adapters.cas3.CasAuthenticationHandler of the Acegi Framework. This CAS Handler delegate to AcegiAuthenticationManager which could use LdapAuthenticationProvider. I think you only have to include acegi jars into cas' localPlugins directory and edit deployerConfigContext.xml and build your custom cas.war. see: http://www.acegisecurity.org/guide/springsecurity.html#cas-server-3 Jens 2007/10/22, Matt Raible <matt@...>: > > I'm trying these instructions and I've gotten as far as configuring > security.xml and getting Roller started. In addition to these > instructions, > I had to add casclient.jar to my WEB-INF/lib directory. > > Do you know how I can add users to CAS or how to have it read users from > LDAP? > > Thanks, > > Matt > > On 8/11/07, Phillip Rhodes <mindcrime@...> wrote: > > A few extra note and points of clarification... anybody who's > > trying to implement SSO probably already understands these > > issues (or at least these kinds of issues) but just in case it > > will help somebody: > > > > This configuration still uses the same roller database tables > > and information for authorization. That is, after a user is > > authenticated using CAS, the code will try to look that username > > up in the roller db, in order to set the authorities for the > > user. Additionally, I imagine the Roller code - at some level - expects > > entries in whichever table it uses for user information so it can > > maintain associations between a given user and their blog, etc. > > > > This is important because it implies (in the most common scenario) > > that a user has to be provisioned in TWO databases - whatever CAS is > > authenticating against, and the Roller DB - before they can use > > the system. > > > > There are a couple of ways to mitigate the impact of this. First, if > > you wanted too you could have CAS authenticate against the Roller DB. > > If you want Roller to be the canonical source of authentication > > information for your entire SSO environment, that's fine. I doubt most > > people will want that though. > > > > So, assuming CAS is authenticating against some other database (maybe > > the organization's LDAP server or Active Directory or something) you > > have a couple of options. > > > > IF you can get the appropriate authorization information put into that > > canonical database, then you can point the UserDetailsService at that > > and only maintain users in one place, at least as far as authentication > > and authorization go. Even then I think it'll turn out that entries > > still have to be populated into Roller's user table(s) for maintaining > > associations. The positive about this scenario is that you can probably > > automate the process of populating the roller table. Eg, "here's a new > > user that's authenticated but we don't have a user record for, so let's > > create this user in our db" on the Roller side. > > > > A more elegant solution would be to automatically provision / > > deprovision the user across all systems in response to their creation in > > the canonical identity database. Doing this can obviously get > > complicated, but the basic idea would be to have something like > > a database trigger, or a hook point provided by the identity > > system, send a message to all the systems in the SSO environment > > saying "Hey, user JoeBob has been created, create this guy > > in your own database" or "Hey, user JoeBob has been deleted, get rid > > of your records for him." Implementing this is left as an exercise > > for the reader. :-) > > > > > > > > TTYL, > > > > > > Phil > > > > > -- > http://raibledesigns.com > |
| Free embeddable forum powered by Nabble | Forum Help |