/* * Copyright (C) 2003-2007 eXo Platform SAS. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see. */ package org.exoplatform.services.security.impl; import java.security.Principal; import java.security.acl.Group; import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import javax.security.auth.Subject; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.exoplatform.container.component.ComponentPlugin; import org.exoplatform.container.xml.InitParams; import org.exoplatform.container.xml.ValueParam; import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.organization.Membership; import org.exoplatform.services.organization.OrganizationService; import org.exoplatform.services.security.SecurityService; import org.exoplatform.services.security.SubjectEventListener; import org.exoplatform.services.security.jaas.JAASGroup; import org.exoplatform.services.security.sso.SSOAuthenticationConfig; import org.exoplatform.services.security.sso.impl.BaseSSOAuthentication; /** * Created y the eXo platform team User: Benjamin Mestrallet Date: 28 avr. 2004 */ public class SecurityServiceImpl implements SecurityService { protected static Log log_ = ExoLogger.getLogger("core.SecurityServiceImpl"); private Map subjects; private OrganizationService orgService_; private String authentication_; private BaseSSOAuthentication SSOAuthentication_; protected static ThreadLocal currentUserHolder = new ThreadLocal (); public SecurityServiceImpl( OrganizationService organizationService, InitParams params) { orgService_ = organizationService; subjects = new HashMap(); ValueParam param = params.getValueParam("security.authentication"); authentication_ = null; SSOAuthentication_ = null; if (param != null) authentication_ = param.getValue(); if (authentication_ == null || authentication_.equals("")) authentication_ = SecurityService.STANDALONE_AUTHENTICATION; } public boolean authenticate(String login, String password) throws Exception { if (password == null || "".equals(password)) { log_.debug("password must not be null or empty"); throw new Exception("password must not be null or empty"); } boolean result = orgService_.getUserHandler().authenticate(login, password); return result; } public void setUpAndCacheSubject(String userName, Subject value) throws Exception { Set principals = value.getPrincipals(); principals.add(new UserPrincipalImpl(userName)); Collection groups = null; try { groups = orgService_.getGroupHandler().findGroupsOfUser(userName); } catch (Exception e) { throw new Exception(e); } Group roleGroup = new JAASGroup(JAASGroup.ROLES); for (Iterator iter = groups.iterator(); iter.hasNext();) { org.exoplatform.services.organization.Group group = (org.exoplatform.services.organization.Group) iter.next(); String groupId = group.getId(); String[] splittedGroupName = StringUtils.split(groupId, "/"); roleGroup.addMember(new RolePrincipalImpl(splittedGroupName[0])); } value.getPrincipals().add(roleGroup); subjects.put(userName, value); currentUserHolder.set(userName); } //Use this for tomcat 5.5.x public void setUpAndCacheSubjectTomcat55(String userName, Subject value) throws Exception { Set principals = value.getPrincipals(); principals.add(new UserPrincipalImpl(userName)); Collection groups = null; try { groups = orgService_.getGroupHandler().findGroupsOfUser(userName); } catch (Exception e) { throw new Exception(e); } for (Iterator iter = groups.iterator(); iter.hasNext();) { org.exoplatform.services.organization.Group group = (org.exoplatform.services.organization.Group) iter.next(); String groupId = group.getId(); String[] splittedGroupName = StringUtils.split(groupId, "/"); value.getPrincipals().add(new RolePrincipalImpl(splittedGroupName[0])); } //value.getPrincipals().add(roleGroup); subjects.put(userName, value); } public boolean isUserInRole(String userName, String role) { Subject subject = (Subject) subjects.get(userName); if (subject == null) return false; Set roleGroups = subject.getPrincipals(Group.class); for (Iterator iter = roleGroups.iterator(); iter.hasNext();) { Group roleGroup = (Group) iter.next(); Enumeration e = roleGroup.members(); while (e.hasMoreElements()) { Principal rolePrincipal = (Principal) e.nextElement(); if (rolePrincipal.getName().equals(role)) return true; } } return false; } public boolean hasMembershipInGroup(String userId, String membershipName, String groupName) { try { if ("*".equals(membershipName)) { // Determine if there exists at least one membership return ! orgService_.getMembershipHandler().findMembershipsByUserAndGroup( userId, groupName).isEmpty(); } else { // Determine if there exists the membership of specified type return orgService_.getMembershipHandler().findMembershipByUserGroupAndType( userId, groupName, membershipName) != null; } } catch(Exception e) { e.printStackTrace(); return false; } } public boolean hasMembershipInGroup(String user, String roleExpression) { if("*".equals(roleExpression)) return true; String membershipName = roleExpression.substring(0, roleExpression .indexOf(":")); String groupName = roleExpression .substring(roleExpression.indexOf(":") + 1); return hasMembershipInGroup(user, membershipName, groupName); } public Subject getSubject(String userName) { log_.debug("get subject for user " + userName); return (Subject) subjects.get(userName); } public void removeSubject(String userName) { log_.debug("remove subject for user " + userName); subjects.remove(userName); } /* (non-Javadoc) * @see org.exoplatform.services.security.SecurityService#getCurrentSubject() */ public Subject getCurrentSubject() { String userName = currentUserHolder.get(); if(userName == null) return null; else return (Subject)subjects.get(userName); } /* (non-Javadoc) * @see org.exoplatform.services.security.SecurityService#setCurrentUser(java.lang.String) */ public void setCurrentUser(String userName) { this.currentUserHolder.set(userName); } public void addSubjectEventListener(SubjectEventListener subjectEventListener) { // To change body of implemented methods use File | Settings | File // Templates. } public String getSSOAuthentication() { if (SSOAuthentication_ != null) return SSOAuthentication_.getSSOAuthenticationConfig().getAuthenticationName() ; else return null ; } public SSOAuthenticationConfig getSSOAuthenticationConfig() { if (SSOAuthentication_ != null) return SSOAuthentication_.getSSOAuthenticationConfig() ; else return null ; } public boolean isSSOAuthentication() { return SecurityService.SSO_AUTHENTICATION.equals(authentication_); } public boolean isStandaloneAuthentication() { return SecurityService.STANDALONE_AUTHENTICATION.equals(authentication_); } public String getProxyTicket(String userName, String urlOfTargetService) throws Exception { if (!this.isSSOAuthentication()) throw new Exception("Portal is configured for standalone authentication. " + "No proxy authentication feature available !") ; if (SSOAuthentication_ == null) throw new Exception("No SSO authentication configured !") ; Iterator iter = this.getSubject(userName).getPrivateCredentials().iterator(); if (!iter.hasNext()) return null; return SSOAuthentication_.getProxyTicket((String) iter.next(), urlOfTargetService) ; } public void setSSOAuthenticationPlugin(ComponentPlugin plugin) { SSOAuthentication_ = (BaseSSOAuthentication) plugin ; } public Log getLog() { return log_; } /** * Intended to be used by subclasses that implement different policies * on setting up and caching the subject. * * @return the list of subjects for the specific user */ public Map getSubjects() { return subjects; } /** * Intended to be used by subclasses that implement different policies * on setting up and caching the subject. * * @return the OrganizationService to be used when processing the user */ public OrganizationService getOrgService() { return orgService_; } }