package org.secnod.dropwizard.shiro; import io.dropwizard.ConfiguredBundle; import io.dropwizard.setup.Bootstrap; import io.dropwizard.setup.Environment; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import javax.servlet.DispatcherType; import javax.servlet.Filter; import org.apache.shiro.realm.Realm; import org.apache.shiro.web.env.IniWebEnvironment; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.web.mgt.WebSecurityManager; import org.apache.shiro.web.servlet.AbstractShiroFilter; import org.glassfish.jersey.server.ResourceConfig; import org.secnod.shiro.jersey.AuthInjectionBinder; import org.secnod.shiro.jersey.AuthorizationFilterFeature; import org.secnod.shiro.jersey.SubjectFactory; /** * A Dropwizard bundle for Apache Shiro. */ public abstract class ShiroBundle<T> implements ConfiguredBundle<T> { @Override public void initialize(Bootstrap<?> bootstrap) { } @Override public void run(T configuration, Environment environment) { ShiroConfiguration shiroConfig = narrow(configuration); ResourceConfig resourceConfig = environment.jersey().getResourceConfig(); resourceConfig.register(new AuthorizationFilterFeature()); resourceConfig.register(new SubjectFactory()); resourceConfig.register(new AuthInjectionBinder()); Filter shiroFilter = createFilter(configuration); environment.servlets() .addFilter("ShiroFilter", shiroFilter) .addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, shiroConfig.filterUrlPattern()); } /** * Narrow down the complete configuration to just the Shiro configuration. */ protected abstract ShiroConfiguration narrow(T configuration); /** * Create the Shiro filter. Overriding this method allows for complete customization of how Shiro is initialized. */ protected Filter createFilter(final T configuration) { ShiroConfiguration shiroConfig = narrow(configuration); final IniWebEnvironment shiroEnv = new IniWebEnvironment(); shiroEnv.setConfigLocations(shiroConfig.iniConfigs()); shiroEnv.init(); AbstractShiroFilter shiroFilter = new AbstractShiroFilter() { @Override public void init() throws Exception { Collection<Realm> realms = createRealms(configuration); WebSecurityManager securityManager = realms.isEmpty() ? shiroEnv.getWebSecurityManager() : new DefaultWebSecurityManager(realms); setSecurityManager(securityManager); setFilterChainResolver(shiroEnv.getFilterChainResolver()); } }; return shiroFilter; } /** * Create and configure the Shiro realms. Override this method in order to * add realms that require configuration. * * @return a non-null list of realms. If empty, no realms will be added, but depending on the content of the INI * file Shiro might still add its automatic IniRealm. */ protected Collection<Realm> createRealms(T configuration) { return Collections.emptyList(); } }