Hi,
I finally configured Oracle SSO with Alfresco. Below is how i achieved that.
I need to run Alfresco on tomcat deployed on other virtual terminal, i created a class file as under
-> STEP 1
I finally configured Oracle SSO with Alfresco. Below is how i achieved that.
I need to run Alfresco on tomcat deployed on other virtual terminal, i created a class file as under
-> STEP 1
package my.custom; import java.io.IOException; import java.util.List; import java.util.Locale; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.transaction.UserTransaction; import org.alfresco.model.ContentModel; import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationException; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.transaction.TransactionService; import org.alfresco.web.app.Application; import org.alfresco.web.app.servlet.AbstractAuthenticationFilter; import org.alfresco.web.app.servlet.AuthenticationHelper; import org.alfresco.web.bean.LoginBean; import org.alfresco.web.bean.repository.User; import org.alfresco.web.config.LanguagesConfigElement; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.extensions.config.ConfigService; import org.springframework.extensions.surf.util.I18NUtil; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import org.alfresco.web.bean.repository.Repository; public class OSSOAuthenticationFilter extends AbstractAuthenticationFilter implements Filter { private static final String LOCALE = "locale"; public static final String MESSAGE_BUNDLE = "alfresco.messages.webclient"; private static Log logger = LogFactory.getLog(OSSOAuthenticationFilter.class); private ServletContext context; private String loginPage; private AuthenticationComponent authComponent; private AuthenticationService authService; private TransactionService transactionService; private PersonService personService; private NodeService nodeService; private Listm_languages; public OSSOAuthenticationFilter() { super(); } public void destroy() { // Nothing to do } /** * Run the filter * * @param sreq * ServletRequest * @param sresp * ServletResponse * @param chain * FilterChain * @exception IOException * @exception ServletException */ public void doFilter(ServletRequest sreq, ServletResponse sresp, FilterChain chain) throws IOException, ServletException { // Get the HTTP request/response/session HttpServletRequest req = (HttpServletRequest) sreq; HttpServletResponse resp = (HttpServletResponse) sresp; HttpSession httpSess = req.getSession(true); String userName = null; //Get headers setted by the oracle sigle sign one server java.util.Enumeration reqMap = req.getHeaders("Osso-User-Dn"); if (reqMap == null) { logger.error("No user logged in"); } else { while (reqMap.hasMoreElements()){ //Get from the full dn the username userName = ((String)reqMap.nextElement()).split(",")[0].trim().toString().split("=")[1].trim().toString(); //String tmp = value.split(",")[0].trim().toString(); //userName = tmp.split("=")[1].trim().toString(); } } if (logger.isDebugEnabled()) { logger.debug("OSSO : User = " + userName); } // See if there is a user in the session and test if it matches User user = (User) httpSess.getAttribute(AuthenticationHelper.AUTHENTICATION_USER); if (user != null) { try { // Debug if (logger.isDebugEnabled()) logger.debug("OSSO : User " + user.getUserName() + " validate ticket"); if (user.getUserName().equals(userName)) { UserTransaction tx1 = transactionService.getUserTransaction(); try { tx1.begin(); authComponent.setCurrentUser(user.getUserName()); tx1.commit(); }catch(Exception ex){ logger.error("Failed due to transaction " + ex); try { tx1.rollback(); } catch (Exception ex2) { logger.error("Failed to rollback transaction", ex2); } } I18NUtil.setLocale(Application.getLanguage(httpSess)); chain.doFilter(sreq, sresp); return; } else { // No match //setAuthenticatedUser(req, httpSess, userName); //below url is th oracle portal url resp.sendRedirect("http://hostname:7778/alfresco"); return; } } catch (AuthenticationException ex) { if (logger.isErrorEnabled()) logger.error("Failed to validate user " + user.getUserName(), ex); } } setAuthenticatedUser(req, httpSess, userName); // Redirect the login page as it is never seen as we always login by name if (req.getRequestURI().endsWith(getLoginPage()) == true) { if (logger.isDebugEnabled()) logger.debug("Login page requested, chaining ..."); resp.sendRedirect(req.getContextPath() + "/faces/jsp/browse/browse.jsp"); return; } else { //below url is th oracle portal url resp.sendRedirect("http://hostname:7778/alfresco"); //chain.doFilter(sreq, sresp); return; } } /** * Set the authenticated user. * * It does not check that the user exists at the moment. * * @param req * @param httpSess * @param userName */ private void setAuthenticatedUser(HttpServletRequest req, HttpSession httpSess, String userName) { if (userName != null){ UserTransaction tx1 = transactionService.getUserTransaction(); // Set the authentication try { tx1.begin(); authComponent.setCurrentUser(userName); tx1.commit(); } catch (Throwable ex) { logger.error(ex); try { tx1.rollback(); } catch (Exception ex2) { logger.error("Failed to rollback transaction", ex2); } } // Set up the user information UserTransaction tx = transactionService.getUserTransaction(); NodeRef homeSpaceRef = null; User user; try { tx.begin(); user = new User(userName, authService.getCurrentTicket(), personService.getPerson(userName)); homeSpaceRef = (NodeRef) nodeService.getProperty(personService.getPerson(userName), ContentModel.PROP_HOMEFOLDER); if(homeSpaceRef == null) { logger.warn("Home Folder is null for user '"+userName+"', using company_home."); homeSpaceRef = (NodeRef) nodeService.getRootNode(Repository.getStoreRef()); } user.setHomeSpaceId(homeSpaceRef.getId()); tx.commit(); } catch (Throwable ex) { logger.error(ex); try { tx.rollback(); } catch (Exception ex2) { logger.error("Failed to rollback transaction", ex2); } if (ex instanceof RuntimeException) { throw (RuntimeException) ex; } else { throw new RuntimeException("Failed to set authenticated user", ex); } } // Store the user httpSess.setAttribute(AuthenticationHelper.AUTHENTICATION_USER, user); httpSess.setAttribute(LoginBean.LOGIN_EXTERNAL_AUTH, Boolean.TRUE); // Set the current locale from the Accept-Lanaguage header if available Locale userLocale = parseAcceptLanguageHeader(req, m_languages); if (userLocale != null) { httpSess.setAttribute(LOCALE, userLocale); httpSess.removeAttribute(MESSAGE_BUNDLE); } // Set the locale using the session I18NUtil.setLocale(Application.getLanguage(httpSess)); } } public void init(FilterConfig config) throws ServletException { this.context = config.getServletContext(); WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(context); ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY); transactionService = serviceRegistry.getTransactionService(); nodeService = serviceRegistry.getNodeService(); authComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent"); authService = (AuthenticationService) ctx.getBean("authenticationService"); personService = (PersonService) ctx.getBean("personService"); // Get a list of the available locales ConfigService configServiceService = (ConfigService) ctx.getBean("webClientConfigService"); LanguagesConfigElement configElement = (LanguagesConfigElement) configServiceService.getConfig("Languages").getConfigElement(LanguagesConfigElement.CONFIG_ELEMENT_ID); m_languages = configElement.getLanguages(); } /** * Return the login page address * * @return String */ private String getLoginPage() { if (loginPage == null) { loginPage = Application.getLoginPage(context); } return loginPage; } }
-> STEP 2 Place this class file under
C:\Alfresco\tomcat\webapps\alfresco\WEB-INF\classes\my\custom
-> STEP 3 Now you need to configure proxy pass in oc4j's httpd.conf file
$ORACLE_HOME/Apache/Apache/conf/httpd.conf, add the following entries: ProxyPass /alfresco/ http://host:8080/alfresco/ ProxyPass /alfresco http://host:8080/alfresco/ ProxyPassReverse /alfresco/ http://host:8080/alfresco/ ProxyPassReverse /alfresco http://host:8080/alfresco/
-> STEP 4 Now you need to enable sso on oracle portal
edit $ORACLE_HOME/Apache/Apache/conf/mod_osso.conf, add the following lines just before the :require valid-user AuthType Basic require valid-user AuthType Basic Please restart apache after you have made this configuration
-> STEP 5 If alfresco is already running then stop and start alfresco service from start menu under start -> alfresco -> stop alfreco virtual server
Thats it, now oracle sso is configured successfully for Alfreco
Try opening http://oc4jserverhost/alfresco, it will redirect to oracle portal sso login page, enter credentials, it will then redirect you to alfresco home page on successful login.
LOGOUT Link
Coming towards logout functionality, i need to make some changes to use oracle portal logout instead of alfresco built in logout.
You need to edit file C:\Alfresco\tomcat\webapps\alfresco\jsp\parts\titlebar.jsp
search for
a:actionLink
now replace that line with
a:actionLink id="logout" image="/images/icons/logout.gif" value="#{msg.logout} (#{NavigationBean.currentUser.userName})" rendered="#{!NavigationBean.isGuest}" href="http://hostname/pls/orasso/orasso.wwsso_app_admin.ls_logout?p_done_url=http%3A%2F%2Fhostname%2Falfresco" immediate="true"
Thats it, now logout functionality is integrated with oracle sso.
Any issues implementing this, feel free to contact me..
Cheers,
Ujjwal Soni