As part of our installation we want to enable single sign on to Clearspace from our Corporate Portal and our Virtual Learning Envionment.
We currently have LDAP integration enabled in Clearspace.
Our Corporate Portal and Clearspace share the same LDAP directory.
Our virtual learning environment uses the same usernames and passwords but doesn't share the same directory (they are centrally synchronized).
Our preferred way to implement this would be to use our Corporate CAS (Yale Central Authentication Server) that is integrated into our Corporate Portal. You get a CAS ticket when you login in to our Corporate Portal.
I know that Clearspace uses the Acegi security system that has support for CAS as either client or server or both.
My questions are if you can answer them.
Can I configure Clearspace to use the CAS via the acegi security system? We would need Clearspace to be a CAS client only.
Can this be used with the LDAP integration?
Does this prevent users from logging in manually? ie can these authentication methods be chained?
If this is not possible is there a recommended way to implement Single Sign on into Clearspace from another application?
Hey Chris,
We actually have some documentation available to cover this subject, available here: http://www.jivesoftware.com/builds/docs/clearspace_community/latest/ExampleAuthenticationandAuthorization.html
Reading through that should give you a bit more information about how authentication takes place within Clearspace.
Can I configure Clearspace to use the CAS via the acegi security system? We would need Clearspace to be a CAS client only.
Typical SSO implementations usually check for a specific header or cookie from the end user to signify their validation with an external authentication server. If CAS provides the necessary access to Clearspace for authentication I believe a plugin could be written to authenticate users against CAS instead of the password stored in the database, or instead of LDAP.
Can this be used with the LDAP integration?
In Clearspace LDAP integration really means two things: The user will authenticate against the LDAP server, and not clearspace. And some or all of the users profile information ( name, email, address ) will be pulled from LDAP. I don't believe it is possible to implement an SSO that uses LDAP to sync profile information, but authenticate with a different server. If you'd like I can do some more research around this question to get a more solid answer.
Does this prevent users from logging in manually? ie can these authentication methods be chained?
This depends on the implementation. You could have your SSO not allow anyone to log into Clearspace directly, and only allow users access when they've authenticated with your external server. You could also have Clearspace display the default login prompt, but check against your external authentication server in the background.
If this is not possible is there a recommended way to implement Single Sign on into Clearspace from another application?
As I mentioned above, the typical SSO implementation involves unauthenticated users being redirected to an external authority to authenticate. That external authority would place a header on the end-users request, or a cookie on the clients machine to signify their credentials. There are, however many other ways the authentication take place. Hopefully after reading the documentation I linked above you'll have a better understanding on what's involved with authenticating users in Clearspace.
If you have any other questions, or would like me to go into more detail on a specific aspect please let me know.
Hello Sean
I'm working with Chris on our SSO into clearspace and I just wanted to confirm something with you.
Chris asked "Can I configure Clearspace to use the CAS via the acegi security system?" and you said
"I believe a plugin could be written to authenticate users against CAS...."
Does this mean you believe using the Acegi security implementation of CAS (http://www.acegisecurity.org/guide/springsecurity.html#cas-client ) would not be recommended as it would not work , but writing a plugin would?
I ask as it looks like clearspace uses acegi and when I try and mesh this with CAS I'm getting alot of conflicts to the extent that I'm wondering if Clearspace Acegi customisation are a barrier to CAS Acegi customisation? This is my first use of Acegi so thought I'd ask.
Best Wishes
Nomit
Hey Nomit,
Simply changing the spring config to use the CAS filter almost certainly won't work. You'll need to provide information to Clearspace on how to handle the incoming request, how to process it, and what to do if the user does not exist. The easiest way to accomplish these tasks is to write an SSO plugin for Clearspace. For more information on SSO plugins, please have a look at our documentation, available here.
If you have any other questions please let me know.
Hello Sean
I'm getting there with the SSO part of my Plugin but am now trying to sync profile and group information from our LDAP.
This is something we had working out of the box when we configured clearspace to use our LDAP as part of the setup process on first access.
I noticed your reply to Chris below
Can this be used with the LDAP integration?
In Clearspace LDAP integration really means two things: The user will authenticate against the LDAP server, and not clearspace. And some or all of the users profile information ( name, email, address ) will be pulled from LDAP. I don't believe it is possible to implement an SSO that uses LDAP to sync profile information, but authenticate with a different server. If you'd like I can do some more research around this question to get a more solid answer.
and would be interested if you could see if it is possible
Looking at our clearspace set up we are using com.jivesoftware.base.profile.MultiProviderUserManager but I can't find anything at http://www.jivesoftware.com/builds/docs/clearspace/latest/javadoc/api/index.html that mentions this class.
Cheers
Nomit
Hey Nomit,
If you want to use an SSO as well as sync your user's profile information with LDAP, you'll need to allow your custom SSO to sync the profiles, instead of configuring Clearspace to use LDAP. You can do this by using the example SSO documentation I liked above. What you'd want to do is implement your own IdentityProviderUserAgent and inject it into the FederatedIdentityAuthFilter. The FederatedIdentityAuthFilter will call IdentityProviderUserAgent.extractUserFromRequest(). This method is expected to return a UserTemplate object, that will be passed to MultiProviderUserManager, which will be responsible for creating/updating the user. Your IdentityProviderUserAgent will be responsible for connecting to your LDAP server ( or retrieving profile data in some way ) and building the UserTemplate object, and setting the proper flags ( such as federated ) to ensure the user's profile will be updated when they login, and not be editable in any other way from within Clearspace.
The example SSO linked above, combined with the information I provided here should give you an idea of what you must to do implement an SSO that syncs user profile data with LDAP ( or any other user store for that matter ).
If you have any other questions on this please let me know.
Hi Sean
Thanks for that.
Good to have what you suspect, officially confirmed!
Cheers
Nomit
Hey Nomit,
Not a problem, just let me know if you have any other questions ![]()
Hello Sean
I was wondering if I could ask a questions on stuff I' now looking into.
I've written the plugin to work with CAS and create and populate a UserTemplate object.
However I have noticed that in the admin interface you can configure associations between cleaspace people attributes like department, address and phone number against ldap. How do I populate these in java or will they always be populated by clearspace when it sychronises a user? Also will a user get synched against ldap changes each time they login given I have done thhe following
user.setFederated(true);
user.setExternal(false);
user.setEnabled(true);
Regards
Nomit
Hi Sean
I have tested the below and:
1 Using my auth and login plugin attributes like Department and Telephone number are not getting populated. They were without the plugin.
2 Also without the plugin ldap changes are reflected in clearspace so I guess I'd like to know how to ensure this happens with my plugin.
Cheers
Nomit
Hey Nomit,
If you're using your own plugin, you're no longer using Clearspace's LDAP integration to sync and authenticate. In order for your fields to be synchronized on login, your filter is going to have to query that information from LDAP, and add the new data to the userTemplate object before it is passed to the MultiProviderUserManager.
Hello
Yes that makes sense but sorry, I was also asking how I do this as there does not seem to be the supporting API methods.
Looking http://www.jivesoftware.com/builds/docs/clearspace/latest/javadoc/api/index.html there are no setter methods for dept or tel number. Am I supposed to use setProperties(Map<String,String> properties) and setSetPropertyEditSupported (boolean setPropertyEditSupported)?
Cheers
Nomit
Hey Nomit,
In order to access the profile fields that are not considered basic ( username, email, etc. ) you'll want to use the ProfileManager. I'd recommend injecting the profile manager into your filter so that you can create your UserTemplate objects, and use them to retrieve profile fields in a map. From there you can iterate through and update the necessary fields.
If you have further questions, please let me know.
hello
So I should implement the
com.jivesoftware.community.user.profile.ProfileManager interface
with my own logic to update the user profile info held in the clearspace database?
So I need to write the code from the ground upwards?
Sorry to always ask but I don't want to reinvent anything that clearspace has I can use. Which cleaspace class currently does this job?
By the way is there any documentation for this part of my plugin's job in the same way there was documentation for authentication?
Cheers
Nomit
You shouldn't need to implement your own ProfileManager; the ProfileManager that is already implemented should fulfill your needs. Injecting the ProfileManager that exists within core code will give you access to all of a user's profile fields. From there, you can do some work to figure out what's been updated, and make those changes.
This portion of your implementation is a little less generic; Unfortunately there is no documentation that covers this specific aspect.
right.
In my spring.xml, how do I refer to it?
I tried doing
<property name="profileManager" ref="profileManagerImpl"/>
to inject the profile manager in but got a nullpointer.
I then greped through the clearspace webapp directory and found no refernce to a profilemanager. The only spring file I can find is WEB-INF/classes/spring-aopContext.xml and that doesn't give any clues either.
Can you be a bit more explicit on how I inject a profileManager please
Cheers
Nomit
Hey Nomit,
I suspect you're missing a setter within your class for the ProfileManager. If you have a look at the Spring Documentation, specifically the xmlBean Factor Example, you'll see that there are two portions of a spring injection, the XML configuration file, and the setter on the destination class.
Also if you're interested we offer a number of developer courses designed to get you ramped up on spring, struts, and our usage of them within our application. If this is something you're interested in just let me know and I'll get you in touch with the proper people.
Hello
I've been a spring course so know about the xml or annotation config and how injection works. It was an error in my xml config that was the problem. ![]()
when I get a map of ProfileFieldValues from the profileManage:
Map<Long,ProfileFieldValue> m = profileManager.getProfile(user);
for (Long key : m.keySet())
{
ProfileFieldValue p = m.get(key);
}
getter methods on ProfileFieldValue do not seem to return the name of the ldap field even though I can get the value of the field??
Does the Long key relate to the ldap field name somehow or am I somehow able to get hold of the
com.jivesoftware.community.user.profile.ProfileField?
just spotted the ProfileFieldManager - will look at that too anbd see if the ID from the profileField relate
to id of the profilefieldvalue
Cheers
Hey Nomit,
Using the profileFieldID you get from the ProfileManager, you can retrieve the actual profile field object from the ProfileFieldManager.
Is this method getting you all the information you need?
Hello
A quick question about logout from clearspace.
When a user clicks logout they seem to get redirected from logout.jspa to index.jspa.
Index.jspa is both the login page and the logged in page.
Our custom auth filter uses an external Authentication system that still has you logged in.
As index.jspa is protected by this filter a user logging out gets logged back in straight away!
The only thing that changes in a browser session on the logout seems to be a cooke set
Set-Cookie: ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/clearspace
but this does not get sent with the redirect to index.jspa so I'm not sure how to capture the logout redirect to index.jspa in my filter.
Can you configure a clearspace login page to be differerent to the logged in page?
Regards
Nomit
Hey Nomit,
You can configure the logout action to redirect to a page other than index.jspa. That way you wont get this look when a user attempts to log out.
"You can configure the logout action to redirect to a page other than index.jspa. That way you wont get this look when a user attempts to log out."
How would I do this exactly?
cheers
Nomit
Hey Nomit,
You can just modify the logout action entry in struts-community.xml. The default entry for logout looks like this:
<action name="logout" class="com.jivesoftware.community.action.LogoutAction">
<result name="success" type="redirect">index.jspa</result>
</action>
You could change it to the following:
<action name="logout" class="com.jivesoftware.community.action.LogoutAction">
<result name="success" type="redirect">http://www.google.com</result>
</action>
The above action definition will redirect you to google.com when you logout.
Hello Sean
One more question about configuring your own custom login filter.
I've set up the filters as described at
http://www.jivesoftware.com/builds/docs/clearspace/latest/ExampleAuthenticationandAuthorization.html
but this forces people to login for public pages as well.
How do I let people through to public pages that should not require a login?
Is there another way to configure the filters, or is the answer in the code?
Any pointers would be appreciated
Thanks
There are two possible issues here: You might have guest access disabled, or your filter doesn't allow anonymous users.
For the first case, you can check the system properties list in in the admin console under 'Management'->'System Properties'. You're looking for jive.auth.disallowGuest. If you want anonymous access, you'll want to set this property to be false.
In your auth filter you'll want to allow for anonymous auth tokens. Essentially instead of hard failing if a user's credentials cannot be determine from the request, you create a new anonymous auth token for them.
Hello
Thanks for that.
How does my filter check that the request is for public/open content?
If I create a public grp with the url
http://localhost:8080/clearspace/groups/publc-test-grp?view=overview
how does my filter know this is public and allow anon access?
Cheers
Nomit
Hi Nomit,
This shouldn't be something that your filter knows or needs to know--it only needs to be concerned with authenticating users. You'll either return an anonymous auth token or, upon a successful authentication of an actual user, the user's auth token. Clearspace will handle all of the authorization aspects for you transparently. If the user is trying to access a protected resource (based on the permissions you have defined in the admin console), an UnauthorizedException will be thrown, thus redirecting the user to a login page.
Thanks,
Austen
However we have defined the filter as
/**=httpSessionContextIntegrationFilter, sessionTrackingFilter,
federatedIdentityAuthFilter, rememberMeProcessingFilter,
feedBasicAuthenticationFilter,exceptionTranslationFilter,jiveAuthenticationTranslationFilter
in the spring.xml.
this is different to that described at
but was taken out of the spring-securityContext.xml in the clearspace
jar itself.
Should the httpSessionContextIntegrationFilter be adding the
|AnonymousAuthentication for my |federatedIdentityAuthFilter to check?
The link about seems to say that
"As part of the authentication contract, if no authentication is present
when the |JiveAuthenticationTranslationFilter| is invoked, the
|AnonymousAuthentication| will be set to the |SecurityContext| prior to
transferring control to the application layer."
the |JiveAuthenticationTranslationFilter is further down the chain.
I've sent up a open group and my filter is still requesting our custom
authentication to be called
Cheers
|
so you
Hi Austen
Can you please ring Nomit on +44 114 2221162 - he is in all afternoon.
Thanks
Nomit,
Please let me know if you have any more questions about this. To recap:
Thanks,
Austen
hello austen
thanks again for the contact.
I forgot to ask a question about the /template/global/unauth.ftl and
/template/global/login.ftl files I'm editing.
Can I override the files by creating custom files?
I did this for changing the logout action in struts-community.xml by
adding to a struts-community-custom.xml file. This would be preferable
due losing custom changes after upgrades?
Cheers
Nomit
This would be preferable
due losing custom changes after upgrades?
It is actually preferable to use a theme as these are stored in your jiveHome/themes and will not be lost during an upgrade. If you override the global results, you'll need to reapply your customizations every patch release.
Thanks,
Austen
This is probably because you have removed the formProcessingFilter from your filter chain. Add this property to your authentication filter bean and it should work again:
<property name="filterProcessesUrl"><value>/cs_login</value></property>
And if I set up, in my filter impl, a filterProcessesUrl instance
variable and a setter on it do I need to do anything else?
My Filter doesn't extend any clearspace filter.....
cheers
Sorry, please ignore my earlier advice about the /cs_login. You really want to redirect back to the login.jspa from your SSO. See here instructions here for how to setup the redirect to your SSO and what URL to return to:
http://www.jivesoftware.com/jivespace/thread/38369
Thanks,
Austen
I might try the
"Another option would be to override the struts-community.xml and make
the changes to the global results for login, unauthenticated and
unauthorized"
would that work here?
could I do this in struts-community-custom.xml?
If so them I'm only changing one resource/file
cheers
Nomit,
As I mentioned above, this is not the preferred way to go as you will need to update this every time you update to the latest patch release. The preferred way to do this is in a theme.
Thanks,
Austen
Okay
but i've already updated struts-community-custom.xml
to override the logout action.
Should I have done that somewhere else as well?
Cheers
Yes, this should be done from within your plugin. The best thing to do would be supply a new definition for the logout action in your plugin's struts.xml file. You shouldn't need to override any core code.
okay
so to finally confrim, recommended path is
1 Overriding logout action should be in plugin struts.xml file and not
clearspace struts-community.xml or struts-community-custom.xml
2 adding redirect as described at
http://www.jivesoftware.com/jivespace/thread/38369 should be done as
part of a theme and not in any struts file (in plugin or otherwise)?
regards
Correct
Hello
This all worked fine - thanks for that.
One issue however, is that the guest pages have a dynamic "login" link
on them that does post to /clearspace/cs_login.
Can this be turned off or can the login link be forced to redirect to
our SSO server as well?
Cheers
Nomit
Hey Nomit,
You can change the action that this link uses, or you can theme it out all together, forcing users to go to your main login page.
Hello
I had my plugin working fine on 2.5.6 and then moved to 2.5.11 and my
plugin does not seem to be intstalled and I'm getting the folllowing error.
18 May 2009 14:49:06,203 http://www.jivesoftware.com/jivespace/message/212173#212173/http-8080-Processor100 ERROR
/clearspace.[default] - Servlet.service() for servlet default threw
exception
The package name 'community-custom' at location package -
file:///home/cs1hsb/clearspace/jivehome/cache/plugins/custom-authentication/struts.xm
l:3:66 is already been used by another package at location package -
file:/usr/local/tomcat/webapps/clearspace/WEB-INF/classes/struts-community
-custom.xml:6:66 - package -
file:///home/cs1hsb/clearspace/jivehome/cache/plugins/custom-authentication/struts.xml:3:66
at
com.jivesoftware.community.web.struts.JiveXworkConfiguration.addPackageConfig(JiveXworkConfiguration.java:105)
at
com.jivesoftware.base.plugin.PluginConfigurationProvider.addPackage(PluginConfigurationProvider.java:479)
at
com.jivesoftware.base.plugin.PluginConfigurationProvider.loadPackages(PluginConfigurationProvider.java:264)
at
com.jivesoftware.community.web.struts.JiveXworkConfiguration.reload(JiveXworkConfiguration.java:168)
at
com.opensymphony.xwork2.config.ConfigurationManager.reload(ConfigurationManager.java:188)
at
com.jivesoftware.community.web.struts.JiveFilterDispatcher.reloadConfiguration(JiveFilterDispatche
my struts.xml file is being used to override logout behaviour
i was told to add this in my own struts file as opposed to in
/usr/local/tomcat/webapps/clearspace/WEB-INF/classes/struts-community-custom.xml
regards
Nomit
I just deleted the WEB-INF/classes/struts-community-custom.xml file and the plugin loaded.
however my pulugin has an error
18 May 2009 16:36:49,979 [http-8080-Processor98] ERROR [/clearspace].[default] - Servlet.service() for servlet default threw exception
java.lang.NullPointerException
at com.jivesoftware.community.impl.ProfileManagerImpl.getProfile(ProfileManagerImpl.java:58)
at uk.ac.sheffield.cics.clearspace.plugins.auth.UosLdapAgent.convertAttributesToUser(UosLdapAgent.java:134)
at uk.ac.sheffield.cics.clearspace.plugins.auth.UosLdapAgent.extractUser(UosLdapAgent.java:86)
at uk.ac.sheffield.cics.clearspace.plugins.auth.CasAuthFilter.doFilter(CasAuthFilter.java:119)
at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:249)
at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainPr
from the line
Map<Long,ProfileFieldValue> m = profileManager.getProfile(jiveRepresentation);
This worked fine in 2.5.6 so not sure if the API has changed accross versions?
Regards
Nomit
If you are getting this error, that means that the jiveRepresentation you are passing into the ProfileManagerImpl getProfile method call is a null value. This is not a null safe method. You must ensure you are passing a non-null User object.
Thanks,
Austen
Nomit,
What is the namespace for your actions in your struts.xml? Is it "/" or simply ""? We upgraded the Struts library to the latest version in the 2.5.10 release and this caused a change in the way the namespace must be mapped, if you are using that option on your actions package. Please change this the other one if you have a package defined for your actions with a namespace of "/" or "".
Thanks,
Austen
Hi,
Iam implementing a SSO to clearspace . Our authentication provider is Siteminder. We are held up in the configuration with following problems
1) Our clearspace site needs to be accessed by Guest users also . So when the user gets into clearspace site we have to show the guest page to users . When the users click on the login button we redirect to Siteminder to authenticate. The problem is if we protect all /clearspace/ in siteminder then we are not getting the guest page .
To acheive this page flow which page should be protected in siteminder ?
2) I wrote a customSSO filter on the basis of federated auth filter (sample given) . When the entire site is protected it seems to be working but it does not help when anonymous users are configured. Also the new filter seem to be executing many times and i do not know what is the reason for it .
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/upgrade/**=httpSessionContextIntegrationFilter, upgradeAuthenticationFilter, upgradeExceptionTranslationFilter,jiveAuthenticationTranslationFilter
/post-upgrade/**=httpSessionContextIntegrationFilter, postUpgradeAuthenticationFilter, postUpgradeExceptionTranslationFilter,jiveAuthenticationTranslationFilter
/admin/**=httpSessionContextIntegrationFilter, sessionTrackingFilter, adminAuthenticationFilter, adminExceptionTranslationFilter,jiveAuthenticationTranslationFilter
/rpc/xmlrpc=wsRequireSSLFilter, httpSessionContextIntegrationFilter, basicAuthenticationFilter, wsExceptionTranslator, jiveAuthenticationTranslationFilter, wsAccessTypeCheckFilter
/rpc/rest/**=wsRequireSSLFilter, httpSessionContextIntegrationFilter, basicAuthenticationFilter, wsExceptionTranslator, jiveAuthenticationTranslationFilter, wsAccessTypeCheckFilter
/rpc/soap/**=wsRequireSSLFilter, httpSessionContextIntegrationFilter, jiveAuthenticationTranslationFilter
/**=httpSessionContextIntegrationFilter, newFilter, sessionTrackingFilter, formAuthenticationFilter, rememberMeProcessingFilter, feedBasicAuthenticationFilter,exceptionTranslationFilter,jiveAuthenticationTranslationFilter
</value>
Can you let me know how to acheive combination of Guest as well as autheticated SSO.
Thanks
The easiest way to do this would be to modify your FederatedIdentityAuthFilter to create an anonymous user auth token if your extractUserFromRequest() method doesn't provide valid credentials.
Thanks Sean,
The Problem was with the code looking for wrong headers . I corrected and it was working. Thanks for the Support.
We have a requirment in such a way that, we need to pass the request url as the service to the CAS server, But the problem is the the serviceproperties was overridden by the admin through Jive Admin Console.
<bean class="com.jivesoftware.community.lifecycle.spring.JivePropertyOverrideConfigurer">
<property name="jivePropertyMappings">
<util:map>
<entry key="casProcessingFilterEntryPoint.loginUrl" value="casProcessingFilterEntryPoint.loginUrl"></entry>
<entry key="ticketValidator.casValidate" value="ticketValidator.casValidate"></entry>
<entry key="serviceProperties.service" value="serviceProperties.service"></entry>
<entry key="casProcessingFilter.filterProcessesUrl" value="casProcessingFilter.filterProcessesUrl"></entry>
<entry key="casGatewayFilter.service" value="casGatewayFilter.service"></entry>
<entry key="casGatewayFilter.loginUrl" value="casGatewayFilter.loginUrl"></entry>
<entry key="casAuthenticationProvider.userCallbackURL" value="casAuthenticationProvider.userCallbackURL"></entry>
</util:map>
</property>
</bean>
<bean id="serviceProperties" class="org.acegisecurity.ui.cas.ServiceProperties">
<property name="service" value=https://localhost:8080/test/j_spring_cas_security_check/>
<property name="sendRenew" value="false"/>
</bean>
Is there any way, we can get rid off this, and sent the user requested url to the CAS server.
Thanks
Ram
Hi Ram,
You're seeing the intended functionality here. The JivePropertyOverrideConigurer is meant to modify the properties for spring beans, and those properties will be overridden in the admin console. In order to have your spring definition take presidence you'll need to remove the appropriate system property from the admin console.
Jive combines the most powerful features of collaboration software, community software,
social networking software & social media monitoring into the leading SBS solution.
© Copyright 2000–2010 Jive Software. All rights reserved.
915 SW Stark St., Suite 400, Portland, OR 97205
Sales: 877-495-3700 | General: 503-295-3700
Privacy Policy | Sitemap | Jobs | Contact Us