/* * Copyright (C) 2007-2012 Argeo GmbH * * Licensed 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. */ package org.argeo.security.jackrabbit; import java.security.Principal; import java.security.acl.Group; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import javax.jcr.Credentials; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.login.LoginException; import org.apache.jackrabbit.core.security.AnonymousPrincipal; import org.apache.jackrabbit.core.security.authentication.AbstractLoginModule; import org.apache.jackrabbit.core.security.authentication.Authentication; import org.apache.jackrabbit.core.security.principal.AdminPrincipal; import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; /** Jackrabbit login mechanism based on Spring Security */ public class ArgeoLoginModule extends AbstractLoginModule { private String adminRole = "ROLE_ADMIN"; private String systemRole = "ROLE_SYSTEM"; /** * Returns the Spring {@link org.springframework.security.Authentication} * (which can be null) */ @Override protected Principal getPrincipal(Credentials credentials) { return SecurityContextHolder.getContext().getAuthentication(); } protected Set getPrincipals() { // use linked HashSet instead of HashSet in order to maintain the order // of principals (as in the Subject). org.springframework.security.core.Authentication authen = (org.springframework.security.core.Authentication) principal; Set principals = new LinkedHashSet(); principals.add(authen); // if (authen instanceof SystemAuthentication) { // principals.add(new AdminPrincipal(authen.getName())); // // principals.add(new ArgeoSystemPrincipal(authen.getName())); // } else if (authen instanceof AnonymousAuthenticationToken) { principals.add(new AnonymousPrincipal()); } else { for (GrantedAuthority ga : authen.getAuthorities()) { if (ga instanceof Principal) principals.add((Principal) ga); // FIXME: make it more generic String authority = ga.getAuthority(); if (adminRole.equals(authority) || systemRole.equals(authority)) principals.add(new AdminPrincipal(authen.getName())); } } // remove previous credentials // Set thisCredentials = subject // .getPublicCredentials(SimpleCredentials.class); // if (thisCredentials != null) // thisCredentials.clear(); return principals; } /** * Super implementation removes all {@link Principal}, the Spring * {@link org.springframework.security.Authentication} as well. Here we * simply clear Jackrabbit related {@link Principal}s. */ // @Override // public boolean logout() throws LoginException { // Set principals = subject.getPrincipals(); // for (Principal principal : subject.getPrincipals()) { // if ((principal instanceof AdminPrincipal) // || (principal instanceof ArgeoSystemPrincipal) // || (principal instanceof AnonymousPrincipal) // || (principal instanceof GrantedAuthority)) { // principals.remove(principal); // } // } // // clearPrincipals(AdminPrincipal.class); // // clearPrincipals(ArgeoSystemPrincipal.class); // // clearPrincipals(AnonymousPrincipal.class); // // clearPrincipals(GrantedAuthority.class); // return true; // } // private void clearPrincipals(Class clss) { // Set principals = subject.getPrincipals(clss); // if (principals != null) // principals.clear(); // } @SuppressWarnings("rawtypes") @Override protected void doInit(CallbackHandler callbackHandler, Session session, Map options) throws LoginException { } @Override protected boolean impersonate(Principal principal, Credentials credentials) throws RepositoryException, LoginException { throw new UnsupportedOperationException( "Impersonation is not yet supported"); } @Override protected Authentication getAuthentication(final Principal principal, Credentials creds) throws RepositoryException { if (principal instanceof Group) { return null; } return new Authentication() { public boolean canHandle(Credentials credentials) { return principal instanceof org.springframework.security.core.Authentication; } public boolean authenticate(Credentials credentials) throws RepositoryException { return ((org.springframework.security.core.Authentication) principal) .isAuthenticated(); } }; } }