| <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>ShiroWebModule.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Shiro :: Support :: Guice</a> > <a href="index.source.html" class="el_package">org.apache.shiro.guice.web</a> > <span class="el_source">ShiroWebModule.java</span></div><h1>ShiroWebModule.java</h1><pre class="source lang-java linenums">/* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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.apache.shiro.guice.web; |
| |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.LinkedHashMap; |
| import java.util.Map; |
| |
| import javax.servlet.Filter; |
| import javax.servlet.ServletContext; |
| |
| import org.apache.shiro.config.ConfigurationException; |
| import org.apache.shiro.env.Environment; |
| import org.apache.shiro.guice.ShiroModule; |
| import org.apache.shiro.mgt.SecurityManager; |
| import org.apache.shiro.session.mgt.SessionManager; |
| import org.apache.shiro.web.env.WebEnvironment; |
| import org.apache.shiro.web.filter.PathMatchingFilter; |
| import org.apache.shiro.web.filter.authc.AnonymousFilter; |
| import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter; |
| import org.apache.shiro.web.filter.authc.FormAuthenticationFilter; |
| import org.apache.shiro.web.filter.authc.LogoutFilter; |
| import org.apache.shiro.web.filter.authc.UserFilter; |
| import org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter; |
| import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter; |
| import org.apache.shiro.web.filter.authz.PortFilter; |
| import org.apache.shiro.web.filter.authz.RolesAuthorizationFilter; |
| import org.apache.shiro.web.filter.authz.SslFilter; |
| import org.apache.shiro.web.filter.mgt.FilterChainResolver; |
| import org.apache.shiro.web.filter.session.NoSessionCreationFilter; |
| import org.apache.shiro.web.mgt.DefaultWebSecurityManager; |
| import org.apache.shiro.web.mgt.WebSecurityManager; |
| import org.apache.shiro.web.session.mgt.ServletContainerSessionManager; |
| |
| import com.google.inject.Binder; |
| import com.google.inject.Key; |
| import com.google.inject.TypeLiteral; |
| import com.google.inject.binder.AnnotatedBindingBuilder; |
| import com.google.inject.name.Names; |
| import com.google.inject.servlet.ServletModule; |
| |
| /** |
| * Sets up Shiro lifecycles within Guice, enables the injecting of Shiro objects, and binds a default |
| * {@link org.apache.shiro.web.mgt.WebSecurityManager}, {@link org.apache.shiro.mgt.SecurityManager} and {@link org.apache.shiro.session.mgt.SessionManager}. At least one realm must be added by |
| * using {@link #bindRealm() bindRealm}. |
| * <p/> |
| * Also provides for the configuring of filter chains and binds a {@link org.apache.shiro.web.filter.mgt.FilterChainResolver} with that information. |
| */ |
| public abstract class ShiroWebModule extends ShiroModule { |
| @SuppressWarnings({"UnusedDeclaration"}) |
| <span class="fc" id="L68"> public static final Key<AnonymousFilter> ANON = Key.get(AnonymousFilter.class);</span> |
| @SuppressWarnings({"UnusedDeclaration"}) |
| <span class="fc" id="L70"> public static final Key<FormAuthenticationFilter> AUTHC = Key.get(FormAuthenticationFilter.class);</span> |
| @SuppressWarnings({"UnusedDeclaration"}) |
| <span class="fc" id="L72"> public static final Key<BasicHttpAuthenticationFilter> AUTHC_BASIC = Key.get(BasicHttpAuthenticationFilter.class);</span> |
| @SuppressWarnings({"UnusedDeclaration"}) |
| <span class="fc" id="L74"> public static final Key<NoSessionCreationFilter> NO_SESSION_CREATION = Key.get(NoSessionCreationFilter.class);</span> |
| @SuppressWarnings({"UnusedDeclaration"}) |
| <span class="fc" id="L76"> public static final Key<LogoutFilter> LOGOUT = Key.get(LogoutFilter.class);</span> |
| @SuppressWarnings({"UnusedDeclaration"}) |
| <span class="fc" id="L78"> public static final Key<PermissionsAuthorizationFilter> PERMS = Key.get(PermissionsAuthorizationFilter.class);</span> |
| @SuppressWarnings({"UnusedDeclaration"}) |
| <span class="fc" id="L80"> public static final Key<PortFilter> PORT = Key.get(PortFilter.class);</span> |
| @SuppressWarnings({"UnusedDeclaration"}) |
| <span class="fc" id="L82"> public static final Key<HttpMethodPermissionFilter> REST = Key.get(HttpMethodPermissionFilter.class);</span> |
| @SuppressWarnings({"UnusedDeclaration"}) |
| <span class="fc" id="L84"> public static final Key<RolesAuthorizationFilter> ROLES = Key.get(RolesAuthorizationFilter.class);</span> |
| @SuppressWarnings({"UnusedDeclaration"}) |
| <span class="fc" id="L86"> public static final Key<SslFilter> SSL = Key.get(SslFilter.class);</span> |
| @SuppressWarnings({"UnusedDeclaration"}) |
| <span class="fc" id="L88"> public static final Key<UserFilter> USER = Key.get(UserFilter.class);</span> |
| |
| |
| static final String NAME = "SHIRO"; |
| |
| /** |
| * We use a LinkedHashMap here to ensure that iterator order is the same as add order. This is important, as the |
| * FilterChainResolver uses iterator order when searching for a matching chain. |
| */ |
| <span class="fc" id="L97"> private final Map<String, Key<? extends Filter>[]> filterChains = new LinkedHashMap<String, Key<? extends Filter>[]>();</span> |
| private final ServletContext servletContext; |
| |
| <span class="fc" id="L100"> public ShiroWebModule(ServletContext servletContext) {</span> |
| <span class="fc" id="L101"> this.servletContext = servletContext;</span> |
| <span class="fc" id="L102"> }</span> |
| |
| public static void bindGuiceFilter(Binder binder) { |
| <span class="nc" id="L105"> binder.install(guiceFilterModule());</span> |
| <span class="nc" id="L106"> }</span> |
| |
| @SuppressWarnings({"UnusedDeclaration"}) |
| public static void bindGuiceFilter(final String pattern, Binder binder) { |
| <span class="nc" id="L110"> binder.install(guiceFilterModule(pattern));</span> |
| <span class="nc" id="L111"> }</span> |
| |
| public static ServletModule guiceFilterModule() { |
| <span class="nc" id="L114"> return guiceFilterModule("/*");</span> |
| } |
| |
| public static ServletModule guiceFilterModule(final String pattern) { |
| <span class="nc" id="L118"> return new ServletModule() {</span> |
| @Override |
| protected void configureServlets() { |
| <span class="nc" id="L121"> filter(pattern).through(GuiceShiroFilter.class);</span> |
| <span class="nc" id="L122"> }</span> |
| }; |
| } |
| |
| @Override |
| protected final void configureShiro() { |
| <span class="fc" id="L128"> bindBeanType(TypeLiteral.get(ServletContext.class), Key.get(ServletContext.class, Names.named(NAME)));</span> |
| <span class="fc" id="L129"> bind(Key.get(ServletContext.class, Names.named(NAME))).toInstance(this.servletContext);</span> |
| <span class="fc" id="L130"> bindWebSecurityManager(bind(WebSecurityManager.class));</span> |
| <span class="fc" id="L131"> bindWebEnvironment(bind(WebEnvironment.class));</span> |
| <span class="fc" id="L132"> bind(GuiceShiroFilter.class).asEagerSingleton();</span> |
| <span class="fc" id="L133"> expose(GuiceShiroFilter.class);</span> |
| |
| <span class="fc" id="L135"> this.configureShiroWeb();</span> |
| |
| <span class="fc" id="L137"> setupFilterChainConfigs();</span> |
| |
| <span class="fc" id="L139"> bind(FilterChainResolver.class).toProvider(new FilterChainResolverProvider(filterChains));</span> |
| <span class="fc" id="L140"> }</span> |
| |
| private void setupFilterChainConfigs() { |
| <span class="fc" id="L143"> Map<Key<? extends PathMatchingFilter>, Map<String, String>> configs = new HashMap<Key<? extends PathMatchingFilter>, Map<String, String>>();</span> |
| |
| <span class="fc bfc" id="L145" title="All 2 branches covered."> for (Map.Entry<String, Key<? extends Filter>[]> filterChain : filterChains.entrySet()) {</span> |
| <span class="fc bfc" id="L146" title="All 2 branches covered."> for (int i = 0; i < filterChain.getValue().length; i++) {</span> |
| <span class="fc" id="L147"> Key<? extends Filter> key = filterChain.getValue()[i];</span> |
| <span class="fc bfc" id="L148" title="All 2 branches covered."> if (key instanceof FilterConfigKey) {</span> |
| <span class="fc" id="L149"> FilterConfigKey<? extends PathMatchingFilter> configKey = (FilterConfigKey<? extends PathMatchingFilter>) key;</span> |
| <span class="fc" id="L150"> key = configKey.getKey();</span> |
| <span class="fc" id="L151"> filterChain.getValue()[i] = key;</span> |
| <span class="pc bpc" id="L152" title="1 of 2 branches missed."> if (!PathMatchingFilter.class.isAssignableFrom(key.getTypeLiteral().getRawType())) {</span> |
| <span class="nc" id="L153"> throw new ConfigurationException("Config information requires a PathMatchingFilter - can't apply to " + key.getTypeLiteral().getRawType());</span> |
| } |
| <span class="pc bpc" id="L155" title="1 of 2 branches missed."> if (configs.get(castToPathMatching(key)) == null) configs.put(castToPathMatching(key), new HashMap<String, String>());</span> |
| <span class="fc" id="L156"> configs.get(castToPathMatching(key)).put(filterChain.getKey(), configKey.getConfigValue());</span> |
| <span class="pc bpc" id="L157" title="1 of 2 branches missed."> } else if (PathMatchingFilter.class.isAssignableFrom(key.getTypeLiteral().getRawType())) {</span> |
| <span class="pc bpc" id="L158" title="1 of 2 branches missed."> if (configs.get(castToPathMatching(key)) == null) configs.put(castToPathMatching(key), new HashMap<String, String>());</span> |
| <span class="fc" id="L159"> configs.get(castToPathMatching(key)).put(filterChain.getKey(), "");</span> |
| } |
| } |
| <span class="fc" id="L162"> }</span> |
| <span class="fc bfc" id="L163" title="All 2 branches covered."> for (Key<? extends PathMatchingFilter> filterKey : configs.keySet()) {</span> |
| <span class="fc" id="L164"> bindPathMatchingFilter(filterKey, configs.get(filterKey));</span> |
| <span class="fc" id="L165"> }</span> |
| <span class="fc" id="L166"> }</span> |
| |
| private <T extends PathMatchingFilter> void bindPathMatchingFilter(Key<T> filterKey, Map<String, String> configs) { |
| <span class="fc" id="L169"> bind(filterKey).toProvider(new PathMatchingFilterProvider<T>(filterKey, configs)).asEagerSingleton();</span> |
| <span class="fc" id="L170"> }</span> |
| |
| @SuppressWarnings({"unchecked"}) |
| private Key<? extends PathMatchingFilter> castToPathMatching(Key<? extends Filter> key) { |
| <span class="fc" id="L174"> return (Key<? extends PathMatchingFilter>) key;</span> |
| } |
| |
| protected abstract void configureShiroWeb(); |
| |
| @SuppressWarnings({"unchecked"}) |
| @Override |
| protected final void bindSecurityManager(AnnotatedBindingBuilder<? super SecurityManager> bind) { |
| <span class="fc" id="L182"> bind.to(WebSecurityManager.class); // SHIRO-435</span> |
| <span class="fc" id="L183"> }</span> |
| |
| /** |
| * Binds the security manager. Override this method in order to provide your own security manager binding. |
| * <p/> |
| * By default, a {@link org.apache.shiro.web.mgt.DefaultWebSecurityManager} is bound as an eager singleton. |
| * |
| * @param bind |
| */ |
| protected void bindWebSecurityManager(AnnotatedBindingBuilder<? super WebSecurityManager> bind) { |
| try { |
| <span class="fc" id="L194"> bind.toConstructor(DefaultWebSecurityManager.class.getConstructor(Collection.class)).asEagerSingleton();</span> |
| <span class="nc" id="L195"> } catch (NoSuchMethodException e) {</span> |
| <span class="nc" id="L196"> throw new ConfigurationException("This really shouldn't happen. Either something has changed in Shiro, or there's a bug in ShiroModule.", e);</span> |
| <span class="fc" id="L197"> }</span> |
| <span class="fc" id="L198"> }</span> |
| |
| /** |
| * Binds the session manager. Override this method in order to provide your own session manager binding. |
| * <p/> |
| * By default, a {@link org.apache.shiro.web.session.mgt.DefaultWebSessionManager} is bound as an eager singleton. |
| * |
| * @param bind |
| */ |
| @Override |
| protected void bindSessionManager(AnnotatedBindingBuilder<SessionManager> bind) { |
| <span class="fc" id="L209"> bind.to(ServletContainerSessionManager.class).asEagerSingleton();</span> |
| <span class="fc" id="L210"> }</span> |
| |
| @Override |
| protected final void bindEnvironment(AnnotatedBindingBuilder<Environment> bind) { |
| <span class="fc" id="L214"> bind.to(WebEnvironment.class); // SHIRO-435</span> |
| <span class="fc" id="L215"> }</span> |
| |
| protected void bindWebEnvironment(AnnotatedBindingBuilder<? super WebEnvironment> bind) { |
| <span class="fc" id="L218"> bind.to(WebGuiceEnvironment.class).asEagerSingleton();</span> |
| <span class="fc" id="L219"> }</span> |
| |
| /** |
| * Adds a filter chain to the shiro configuration. |
| * <p/> |
| * NOTE: If the provided key is for a subclass of {@link org.apache.shiro.web.filter.PathMatchingFilter}, it will be registered with a proper |
| * provider. |
| * |
| * @param pattern |
| * @param keys |
| */ |
| @SuppressWarnings({"UnusedDeclaration"}) |
| protected final void addFilterChain(String pattern, Key<? extends Filter>... keys) { |
| <span class="fc" id="L232"> filterChains.put(pattern, keys);</span> |
| <span class="fc" id="L233"> }</span> |
| |
| protected static <T extends PathMatchingFilter> Key<T> config(Key<T> baseKey, String configValue) { |
| <span class="fc" id="L236"> return new FilterConfigKey<T>(baseKey, configValue);</span> |
| } |
| |
| @SuppressWarnings({"UnusedDeclaration"}) |
| protected static <T extends PathMatchingFilter> Key<T> config(TypeLiteral<T> typeLiteral, String configValue) { |
| <span class="nc" id="L241"> return config(Key.get(typeLiteral), configValue);</span> |
| } |
| |
| @SuppressWarnings({"UnusedDeclaration"}) |
| protected static <T extends PathMatchingFilter> Key<T> config(Class<T> type, String configValue) { |
| <span class="nc" id="L246"> return config(Key.get(type), configValue);</span> |
| } |
| |
| private static class FilterConfigKey<T extends PathMatchingFilter> extends Key<T> { |
| private Key<T> key; |
| private String configValue; |
| |
| private FilterConfigKey(Key<T> key, String configValue) { |
| <span class="fc" id="L254"> super();</span> |
| <span class="fc" id="L255"> this.key = key;</span> |
| <span class="fc" id="L256"> this.configValue = configValue;</span> |
| <span class="fc" id="L257"> }</span> |
| |
| public Key<T> getKey() { |
| <span class="fc" id="L260"> return key;</span> |
| } |
| |
| public String getConfigValue() { |
| <span class="fc" id="L264"> return configValue;</span> |
| } |
| } |
| } |
| </pre><div class="footer"><span class="right">Created with <a href="http://www.eclemma.org/jacoco">JaCoCo</a> 0.7.7.201606060606</span></div></body></html> |