From: Mathieu Baudier Date: Mon, 20 Aug 2012 20:43:31 +0000 (+0000) Subject: Provide dummy user manager for OS security model X-Git-Tag: argeo-commons-2.1.30~863 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=571e877fb974988d07527d4bb5b7e7c5e16ca4fb;p=lgpl%2Fargeo-commons.git Provide dummy user manager for OS security model git-svn-id: https://svn.argeo.org/commons/trunk@5522 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/security/modules/org.argeo.security.dao.ldap/META-INF/spring/security-ldap-osgi.xml b/security/modules/org.argeo.security.dao.ldap/META-INF/spring/security-ldap-osgi.xml index e8a6c0d86..3af0501ed 100644 --- a/security/modules/org.argeo.security.dao.ldap/META-INF/spring/security-ldap-osgi.xml +++ b/security/modules/org.argeo.security.dao.ldap/META-INF/spring/security-ldap-osgi.xml @@ -15,10 +15,8 @@ - - - + diff --git a/security/modules/org.argeo.security.dao.os/META-INF/spring/security-os-osgi.xml b/security/modules/org.argeo.security.dao.os/META-INF/spring/security-os-osgi.xml index 493d80a8b..8c6977a68 100644 --- a/security/modules/org.argeo.security.dao.os/META-INF/spring/security-os-osgi.xml +++ b/security/modules/org.argeo.security.dao.os/META-INF/spring/security-os-osgi.xml @@ -19,4 +19,14 @@ + + + + + \ No newline at end of file diff --git a/security/modules/org.argeo.security.dao.os/META-INF/spring/security-os.xml b/security/modules/org.argeo.security.dao.os/META-INF/spring/security-os.xml index 33b4be32f..41b23cc09 100644 --- a/security/modules/org.argeo.security.dao.os/META-INF/spring/security-os.xml +++ b/security/modules/org.argeo.security.dao.os/META-INF/spring/security-os.xml @@ -67,4 +67,10 @@ + + + + + \ No newline at end of file diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/MatchingAuthenticationProvider.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/MatchingAuthenticationProvider.java index 29f956eb2..c020c2a5c 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/MatchingAuthenticationProvider.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/MatchingAuthenticationProvider.java @@ -30,6 +30,8 @@ import org.springframework.security.providers.dao.AbstractUserDetailsAuthenticat import org.springframework.security.userdetails.User; import org.springframework.security.userdetails.UserDetails; +/** @deprecated */ +@Deprecated public class MatchingAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider { diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/OsAuthenticationProvider.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/OsAuthenticationProvider.java index 33a4f6376..d61354567 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/OsAuthenticationProvider.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/OsAuthenticationProvider.java @@ -29,21 +29,22 @@ import org.springframework.security.providers.AuthenticationProvider; * Validates an OS authentication. The id is that it will always be * authenticated since we are always runnign within an OS, but the fact that the * {@link Authentication} works properly depends on the proper OS login module - * having been called as well. + * having been called as well. TODO make it more configurable (base roles, is + * admin) */ public class OsAuthenticationProvider implements AuthenticationProvider { - private String osUserRole = "ROLE_OS_USER"; - private String userRole = "ROLE_USER"; - private String adminRole = "ROLE_ADMIN"; + final static String osUserRole = "ROLE_OS_USER"; + final static String userRole = "ROLE_USER"; + final static String adminRole = "ROLE_ADMIN"; - private Boolean isAdmin = true; + final static Boolean isAdmin = true; public Authentication authenticate(Authentication authentication) throws AuthenticationException { return new OsAuthenticationToken(getBaseAuthorities()); } - protected GrantedAuthority[] getBaseAuthorities() { + public static GrantedAuthority[] getBaseAuthorities() { List auths = new ArrayList(); auths.add(new GrantedAuthorityImpl(osUserRole)); auths.add(new GrantedAuthorityImpl(userRole)); @@ -57,20 +58,4 @@ public class OsAuthenticationProvider implements AuthenticationProvider { return OsAuthenticationToken.class.isAssignableFrom(authentication); } - public void setOsUserRole(String osUserRole) { - this.osUserRole = osUserRole; - } - - public void setUserRole(String userRole) { - this.userRole = userRole; - } - - public void setAdminRole(String adminRole) { - this.adminRole = adminRole; - } - - public void setIsAdmin(Boolean isAdmin) { - this.isAdmin = isAdmin; - } - } diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/OsJcrAuthenticationProvider.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/OsJcrAuthenticationProvider.java index 4f3e6a18e..917733dbc 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/OsJcrAuthenticationProvider.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/OsJcrAuthenticationProvider.java @@ -19,7 +19,6 @@ import javax.jcr.Node; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; -import javax.jcr.security.Privilege; import org.argeo.ArgeoException; import org.argeo.jcr.JcrUtils; @@ -27,6 +26,9 @@ import org.argeo.security.OsAuthenticationToken; import org.argeo.security.core.OsAuthenticationProvider; import org.springframework.security.Authentication; import org.springframework.security.AuthenticationException; +import org.springframework.security.BadCredentialsException; +import org.springframework.security.providers.UsernamePasswordAuthenticationToken; +import org.springframework.security.userdetails.UserDetails; /** Relies on OS to authenticate and additionally setup JCR */ public class OsJcrAuthenticationProvider extends OsAuthenticationProvider { @@ -35,6 +37,8 @@ public class OsJcrAuthenticationProvider extends OsAuthenticationProvider { private Session securitySession; private Session nodeSession; + private UserDetails userDetails; + public void init() { try { securitySession = repository.login(securityWorkspace); @@ -51,39 +55,50 @@ public class OsJcrAuthenticationProvider extends OsAuthenticationProvider { public Authentication authenticate(Authentication authentication) throws AuthenticationException { - final OsAuthenticationToken authen = (OsAuthenticationToken) super - .authenticate(authentication); - try { - // WARNING: at this stage we assume that the java properties - // will have the same value - String username = System.getProperty("user.name"); - Node userProfile = JcrUtils.createUserProfileIfNeeded( - securitySession, username); - JcrUserDetails.checkAccountStatus(userProfile); - - // each user should have a writable area in the default workspace of - // the node - Node userNodeHome = JcrUtils.createUserHomeIfNeeded(nodeSession, - username); - // FIXME how to set user home privileges *before* it is created ? - // JcrUtils.addPrivilege(nodeSession, userNodeHome.getPath(), - // username, Privilege.JCR_ALL); - // if (nodeSession.hasPendingChanges()) - // nodeSession.save(); - - // user details - JcrUserDetails userDetails = new JcrUserDetails(userProfile, authen - .getCredentials().toString(), getBaseAuthorities()); + if (authentication instanceof UsernamePasswordAuthenticationToken) { + // deal with remote access to internal server + // FIXME very primitive and unsecure at this stage + // consider using the keyring for username / password authentication + // or certificate + UsernamePasswordAuthenticationToken upat = (UsernamePasswordAuthenticationToken) authentication; + if (!upat.getPrincipal().toString() + .equals(System.getProperty("user.name"))) + throw new BadCredentialsException("Wrong credentials"); + UsernamePasswordAuthenticationToken authen = new UsernamePasswordAuthenticationToken( + authentication.getPrincipal(), + authentication.getCredentials(), getBaseAuthorities()); authen.setDetails(userDetails); - } catch (RepositoryException e) { - JcrUtils.discardQuietly(securitySession); - throw new ArgeoException( - "Unexpected exception when synchronizing OS and JCR security ", - e); - } finally { - JcrUtils.logoutQuietly(securitySession); + return authen; + } else if (authentication instanceof OsAuthenticationToken) { + OsAuthenticationToken authen = (OsAuthenticationToken) super + .authenticate(authentication); + try { + // WARNING: at this stage we assume that the java properties + // will have the same value + String username = System.getProperty("user.name"); + Node userProfile = JcrUtils.createUserProfileIfNeeded( + securitySession, username); + JcrUserDetails.checkAccountStatus(userProfile); + + // each user should have a writable area in the default + // workspace of the node + JcrUtils.createUserHomeIfNeeded(nodeSession, username); + userDetails = new JcrUserDetails(userProfile, authen + .getCredentials().toString(), getBaseAuthorities()); + authen.setDetails(userDetails); + return authen; + } catch (RepositoryException e) { + JcrUtils.discardQuietly(securitySession); + throw new ArgeoException( + "Unexpected exception when synchronizing OS and JCR security ", + e); + } finally { + JcrUtils.logoutQuietly(securitySession); + } + } else { + throw new ArgeoException("Unsupported authentication " + + authentication.getClass()); } - return authen; } public void setSecurityWorkspace(String securityWorkspace) { @@ -93,4 +108,12 @@ public class OsJcrAuthenticationProvider extends OsAuthenticationProvider { public void setRepository(Repository repository) { this.repository = repository; } + + @SuppressWarnings("rawtypes") + public boolean supports(Class authentication) { + return OsAuthenticationToken.class.isAssignableFrom(authentication) + || UsernamePasswordAuthenticationToken.class + .isAssignableFrom(authentication); + } + } diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/OsJcrUserAdminService.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/OsJcrUserAdminService.java new file mode 100644 index 000000000..483cc408d --- /dev/null +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/OsJcrUserAdminService.java @@ -0,0 +1,129 @@ +package org.argeo.security.jcr; + +import java.util.HashSet; +import java.util.Set; + +import javax.jcr.Node; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.argeo.ArgeoException; +import org.argeo.jcr.JcrUtils; +import org.argeo.security.UserAdminService; +import org.springframework.dao.DataAccessException; +import org.springframework.security.userdetails.UserDetails; +import org.springframework.security.userdetails.UsernameNotFoundException; + +/** + * Dummy user service to be used when running as a single OS user (typically + * desktop). TODO integrate with JCR user / groups + */ +public class OsJcrUserAdminService implements UserAdminService { + private String securityWorkspace = "security"; + private Repository repository; + + private Session securitySession; + + public void init() { + try { + securitySession = repository.login(securityWorkspace); + } catch (RepositoryException e) { + throw new ArgeoException("Cannot initialize", e); + } + } + + public void destroy() { + JcrUtils.logoutQuietly(securitySession); + } + + /** Unsupported */ + public void createUser(UserDetails user) { + throw new UnsupportedOperationException(); + } + + /** Does nothing */ + public void updateUser(UserDetails user) { + + } + + /** Unsupported */ + public void deleteUser(String username) { + throw new UnsupportedOperationException(); + } + + /** Unsupported */ + public void changePassword(String oldPassword, String newPassword) { + throw new UnsupportedOperationException(); + } + + public boolean userExists(String username) { + if (getSPropertyUsername().equals(username)) + return true; + else + return false; + } + + public UserDetails loadUserByUsername(String username) + throws UsernameNotFoundException, DataAccessException { + if (getSPropertyUsername().equals(username)) { + Node userProfile = JcrUtils.getUserProfile(securitySession, + username); + JcrUserDetails userDetails; + try { + userDetails = new JcrUserDetails(userProfile, "", + OsJcrAuthenticationProvider.getBaseAuthorities()); + } catch (RepositoryException e) { + throw new ArgeoException("Cannot retrieve user profile for " + + username, e); + } + return userDetails; + } else { + throw new UnsupportedOperationException(); + } + } + + protected final String getSPropertyUsername() { + return System.getProperty("user.name"); + } + + public Set listUsers() { + Set set = new HashSet(); + set.add(getSPropertyUsername()); + return set; + } + + public Set listUsersInRole(String role) { + Set set = new HashSet(); + set.add(getSPropertyUsername()); + return set; + } + + /** Does nothing */ + public void synchronize() { + } + + /** Unsupported */ + public void newRole(String role) { + throw new UnsupportedOperationException(); + } + + public Set listEditableRoles() { + Set set = new HashSet(); + return set; + } + + /** Unsupported */ + public void deleteRole(String role) { + throw new UnsupportedOperationException(); + } + + public void setRepository(Repository repository) { + this.repository = repository; + } + + public void setSecurityWorkspace(String securityWorkspace) { + this.securityWorkspace = securityWorkspace; + } + +}