Java tutorial
/******************************************************************************* * Copyright 2008(c) The OBiBa Consortium. All rights reserved. * * This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package org.obiba.agate.security; import java.io.IOException; import java.util.Collection; import java.util.Set; import javax.annotation.PreDestroy; import javax.inject.Inject; import net.sf.ehcache.CacheManager; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.credential.PasswordMatcher; import org.apache.shiro.authc.pam.FirstSuccessfulStrategy; import org.apache.shiro.authc.pam.ModularRealmAuthenticator; import org.apache.shiro.authz.ModularRealmAuthorizer; import org.apache.shiro.authz.permission.PermissionResolver; import org.apache.shiro.authz.permission.PermissionResolverAware; import org.apache.shiro.cache.ehcache.EhCacheManager; import org.apache.shiro.config.Ini; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.DefaultSecurityManager; import org.apache.shiro.mgt.DefaultSubjectDAO; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.realm.Realm; import org.apache.shiro.realm.text.IniRealm; import org.apache.shiro.session.mgt.DefaultSessionManager; import org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler; import org.apache.shiro.session.mgt.SessionValidationScheduler; import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO; import org.apache.shiro.util.LifecycleUtils; import org.obiba.shiro.SessionStorageEvaluator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.FactoryBean; import org.springframework.context.annotation.DependsOn; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.stereotype.Component; import com.google.common.collect.ImmutableList; @Component @DependsOn("cacheConfiguration") public class SecurityManagerFactory implements FactoryBean<SecurityManager> { public static final String INI_REALM = "agate-ini-realm"; private static final long SESSION_VALIDATION_INTERVAL = 3600000l; // 1 hour private static final Logger log = LoggerFactory.getLogger(SecurityManagerFactory.class); @Inject private Set<Realm> realms; @Inject private CacheManager cacheManager; private final PermissionResolver permissionResolver = new AgatePermissionResolver(); private SecurityManager securityManager; @Override public SecurityManager getObject() throws Exception { if (securityManager == null) { securityManager = doCreateSecurityManager(); SecurityUtils.setSecurityManager(securityManager); } return securityManager; } @Override public Class<?> getObjectType() { return DefaultSecurityManager.class; } @Override public boolean isSingleton() { return true; } @PreDestroy public void destroySecurityManager() { log.debug("Shutdown SecurityManager"); // Destroy the security manager. SecurityUtils.setSecurityManager(null); LifecycleUtils.destroy(securityManager); securityManager = null; } private SecurityManager doCreateSecurityManager() { return new CustomIniSecurityManagerFactory(getShiroIniPath()).createInstance(); } private String getShiroIniPath() { try { return new DefaultResourceLoader().getResource("classpath:/shiro.ini").getFile().getAbsolutePath(); } catch (IOException e) { throw new RuntimeException("Cannot load shiro.ini", e); } } private class CustomIniSecurityManagerFactory extends IniSecurityManagerFactory { private CustomIniSecurityManagerFactory(String resourcePath) { super(resourcePath); } @Override @SuppressWarnings("ChainOfInstanceofChecks") protected SecurityManager createDefaultInstance() { DefaultSecurityManager dsm = (DefaultSecurityManager) super.createDefaultInstance(); initializeCacheManager(dsm); initializeSessionManager(dsm); initializeSubjectDAO(dsm); initializeAuthorizer(dsm); initializeAuthenticator(dsm); // ((AbstractAuthenticator) dsm.getAuthenticator()).setAuthenticationListeners(authenticationListeners); return dsm; } private void initializeCacheManager(DefaultSecurityManager dsm) { if (dsm.getCacheManager() == null) { EhCacheManager ehCacheManager = new EhCacheManager(); ehCacheManager.setCacheManager(cacheManager); dsm.setCacheManager(ehCacheManager); } } private void initializeSessionManager(DefaultSecurityManager dsm) { if (dsm.getSessionManager() instanceof DefaultSessionManager) { DefaultSessionManager sessionManager = (DefaultSessionManager) dsm.getSessionManager(); // sessionManager.setSessionListeners(sessionListeners); sessionManager.setSessionDAO(new EnterpriseCacheSessionDAO()); SessionValidationScheduler sessionValidationScheduler = new ExecutorServiceSessionValidationScheduler(); sessionValidationScheduler.enableSessionValidation(); sessionManager.setSessionValidationScheduler(sessionValidationScheduler); sessionManager.setSessionValidationInterval(SESSION_VALIDATION_INTERVAL); } } private void initializeSubjectDAO(DefaultSecurityManager dsm) { if (dsm.getSubjectDAO() instanceof DefaultSubjectDAO) { ((DefaultSubjectDAO) dsm.getSubjectDAO()).setSessionStorageEvaluator(new SessionStorageEvaluator()); } } private void initializeAuthorizer(DefaultSecurityManager dsm) { if (dsm.getAuthorizer() instanceof ModularRealmAuthorizer) { // ((RolePermissionResolverAware) dsm.getAuthorizer()).setRolePermissionResolver(rolePermissionResolver); ((PermissionResolverAware) dsm.getAuthorizer()).setPermissionResolver(permissionResolver); } } private void initializeAuthenticator(DefaultSecurityManager dsm) { if (dsm.getAuthenticator() instanceof ModularRealmAuthenticator) { ((ModularRealmAuthenticator) dsm.getAuthenticator()) .setAuthenticationStrategy(new FirstSuccessfulStrategy()); } } @Override protected void applyRealmsToSecurityManager(Collection<Realm> shiroRealms, @SuppressWarnings("ParameterHidesMemberVariable") SecurityManager securityManager) { super.applyRealmsToSecurityManager( ImmutableList.<Realm>builder().addAll(realms).addAll(shiroRealms).build(), securityManager); } @Override protected Realm createRealm(Ini ini) { // Set the resolvers first, because IniRealm is initialized before the resolvers // are applied by the ModularRealmAuthorizer IniRealm realm = new IniRealm(); realm.setName(INI_REALM); // realm.setRolePermissionResolver(rolePermissionResolver); realm.setPermissionResolver(permissionResolver); realm.setResourcePath(getShiroIniPath()); realm.setCredentialsMatcher(new PasswordMatcher()); realm.setIni(ini); configureUrl(realm.getIni().getSection("urls") == null ? realm.getIni().addSection("urls") : realm.getIni().getSection("urls")); return realm; } @SuppressWarnings("OverlyLongMethod") private void configureUrl(@SuppressWarnings("TypeMayBeWeakened") Ini.Section urls) { urls.put("/ws/logs/**", Roles.AGATE_ADMIN.name()); urls.put("/websocket/tracker", Roles.AGATE_ADMIN.name()); urls.put("/metrics*", Roles.AGATE_ADMIN.name()); urls.put("/metrics/**", Roles.AGATE_ADMIN.name()); urls.put("/health*", Roles.AGATE_ADMIN.name()); urls.put("/health/**", Roles.AGATE_ADMIN.name()); urls.put("/trace*", Roles.AGATE_ADMIN.name()); urls.put("/trace/**", Roles.AGATE_ADMIN.name()); urls.put("/dump*", Roles.AGATE_ADMIN.name()); urls.put("/dump/**", Roles.AGATE_ADMIN.name()); urls.put("/shutdown*", Roles.AGATE_ADMIN.name()); urls.put("/shutdown/**", Roles.AGATE_ADMIN.name()); urls.put("/beans*", Roles.AGATE_ADMIN.name()); urls.put("/beans/**", Roles.AGATE_ADMIN.name()); urls.put("/info*", Roles.AGATE_ADMIN.name()); urls.put("/info/**", Roles.AGATE_ADMIN.name()); urls.put("/autoconfig*", Roles.AGATE_ADMIN.name()); urls.put("/autoconfig/**", Roles.AGATE_ADMIN.name()); urls.put("/env*", Roles.AGATE_ADMIN.name()); urls.put("/env/**", Roles.AGATE_ADMIN.name()); urls.put("/trace*", Roles.AGATE_ADMIN.name()); urls.put("/trace/**", Roles.AGATE_ADMIN.name()); } } }