You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shiro.apache.org by ad...@apache.org on 2009/06/18 05:13:47 UTC
svn commit: r785881 [10/11] - in /incubator/shiro/trunk: ./ all/
core/src/main/java/org/apache/ki/ core/src/main/java/org/apache/shiro/
core/src/main/java/org/apache/shiro/aop/
core/src/main/java/org/apache/shiro/authc/
core/src/main/java/org/apache/sh...
Added: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroFilter.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroFilter.java?rev=785881&view=auto
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroFilter.java (added)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroFilter.java Thu Jun 18 03:13:34 2009
@@ -0,0 +1,623 @@
+/*
+ * 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.web.servlet;
+
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.shiro.config.Configuration;
+import org.apache.shiro.config.ConfigurationException;
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.util.ClassUtils;
+import org.apache.shiro.util.LifecycleUtils;
+import static org.apache.shiro.util.StringUtils.clean;
+import org.apache.shiro.util.ThreadContext;
+import org.apache.shiro.web.DefaultWebSecurityManager;
+import org.apache.shiro.web.WebUtils;
+import org.apache.shiro.web.config.IniWebConfiguration;
+import org.apache.shiro.web.config.WebConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.beans.PropertyDescriptor;
+import java.io.IOException;
+import java.net.InetAddress;
+
+
+/**
+ * Main ServletFilter that configures and enables all Shiro functions within a web application.
+ * <p/>
+ * The following is a fully commented example that documents how to configure it:
+ * <p/>
+ * <pre><filter>
+ * <filter-name>KiFilter</filter-name>
+ * <filter-class>org.apache.shiro.web.servlet.KiFilter</filter-class>
+ * <init-param><param-name>config</param-name><param-value>
+ * #
+ * #NOTE: This config looks pretty long - but its not - its only a few lines of actual config.
+ * # Everything else is just heavily commented to explain things in-depth. Feel free to delete any
+ * # comments that you don't want to read from your own configuration ;)
+ * #
+ * # Any commented values below that _don't_ start with 'example.pkg' are Shiro's defaults. If you want to change any
+ * # values on those lines, you only need to uncomment the lines you want to change.
+ * #
+ * [main]
+ * # The 'main' section defines Shiro-wide configuration.
+ * #
+ * # The configuration is essentially an object graph definition in a .properties style format. The beans defined
+ * # would be those that are used to construct the application's SecurityManager. It is essentially 'poor man's'
+ * # dependency injection via a .properties format.
+ * #
+ * # --- Defining Realms ---
+ * #
+ * # Any Realm defined here will automatically be injected into Shiro's default SecurityManager created at startup. For
+ * # example:
+ * #
+ * # myRealm = example.pkg.security.MyRealm
+ * #
+ * # This would instantiate the some.pkg.security.MyRealm class with a default no-arg constructor and inject it into
+ * # the SecurityManager. More than one realm can be defined if needed. You can create graphs and reference
+ * # other beans ('$' bean reference notation) while defining Realms and other objects:
+ * #
+ * # <b>connectionFactory</b> = example.pkg.ConnectionFactory
+ * # connectionFactory.driverClassName = a.jdbc.Driver
+ * # connectionFactory.username = aUsername
+ * # connectionFactory.password = aPassword
+ * # connectionFactory.minConnections = 3
+ * # connectionFactory.maxConnections = 10
+ * # ... etc...
+ * #
+ * # myJdbcRealm = example.pkg.jdbc.MyJdbcRealm
+ * # myJdbcRealm.connectionFactory = <b>$connectionFactory</b>
+ * # ... etc ...
+ * #
+ * # --- Realm Factories ---
+ * #
+ * # If the .properties style isn't robust enough for your needs, you also have the option of implementing the
+ * # {@link org.apache.shiro.realm.RealmFactory org.apache.shiro.realm.RealmFactory} interface with more complex construction
+ * # logic. Then you can declare the implementation here instead. The realms it returns will be injected in to the
+ * # SecurityManager just as the individual Realms are. For example:
+ * #
+ * # aRealmFactory = some.pkg.ClassThatImplementsRealmFactory
+ * #
+ * # --- SessionManager properties ---
+ * #
+ * # Except for Realms and RealmFactories, all other objects should be defined and set on the SecurityManager directly.
+ * # The default 'securityManager' bean is an instance of {@link org.apache.shiro.web.DefaultWebSecurityManager}, so you
+ * # can set any of its corresponding properties as necessary:
+ * #
+ * # someObject = some.fully.qualified.ClassName
+ * # someObject.propertyN = foo
+ * # ...
+ * # securityManager.someObject = $someObject
+ * #
+ * # For example, if you wanted to change Shiro's default session mechanism, you can change the 'sessionMode' property.
+ * # By default, Shiro's Session infrastructure in a web environment will use the
+ * # Servlet container's HttpSession. However, if you need to share session state across client types
+ * # (e.g. Web MVC plus Java Web Start or Flash), or are doing distributed/shared Sessions for
+ * # Single Sign On, HttpSessions aren't good enough. You'll need to use Shiro's more powerful
+ * # (and client-agnostic) session management. You can enable this by uncommenting the following line
+ * # and changing 'http' to 'shiro'
+ * #
+ * #securityManager.{@link org.apache.shiro.web.DefaultWebSecurityManager#setSessionMode(String) sessionMode} = http
+ * #
+ * [filters]
+ * # This section defines the 'pool' of all Filters available to the url path definitions in the [urls] section below.
+ * #
+ * # The following commented values are already provided by Shiro by default and are immediately usable
+ * # in the [urls] definitions below. If you like, you may override any values by uncommenting only the lines
+ * # you need to change.
+ * #
+ * # Each Filter is configured based on its functionality and/or protocol. You should read each
+ * # Filter's JavaDoc to fully understand what each does and how it works as well as how it would
+ * # affect the user experience.
+ * #
+ * # Form-based Authentication filter:
+ * #<a name="authc"></a>authc = {@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter}
+ * #authc.{@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter#setLoginUrl(String) loginUrl} = /login.jsp
+ * #authc.{@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter#setUsernameParam(String) usernameParam} = username
+ * #authc.{@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter#setPasswordParam(String) passwordParam} = password
+ * #authc.{@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter#setRememberMeParam(String) rememberMeParam} = rememberMe
+ * #authc.{@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter#setSuccessUrl(String) successUrl} = /login.jsp
+ * #authc.{@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter#setFailureKeyAttribute(String) failureKeyAttribute} = {@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter#DEFAULT_ERROR_KEY_ATTRIBUTE_NAME}
+ * #
+ * # Http BASIC Authentication filter:
+ * #<a name="authcBasic"></a>authcBasic = {@link org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter}
+ * #authcBasic.{@link org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter#setApplicationName(String) applicationName} = application
+ * #
+ * # Roles filter: requires the requesting user to have one or more roles for the request to continue.
+ * # If they do not have the specified roles, they are redirected to the specified URL.
+ * #<a name="roles"></a>roles = {@link org.apache.shiro.web.filter.authz.RolesAuthorizationFilter}
+ * #roles.{@link org.apache.shiro.web.filter.authz.RolesAuthorizationFilter#setUnauthorizedUrl(String) unauthorizedUrl} =
+ * # (note the above url is null by default, which will cause an HTTP 403 (Access Denied) response instead
+ * # of redirecting to a page. If you want to show a 'nice page' instead, you should specify that url.
+ * #
+ * # Permissions filter: requires the requesting user to have one or more permissions for the request to
+ * # continue, and if they do not, redirects them to the specified URL.
+ * #<a name="perms"></a>perms = {@link org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter}
+ * #perms.{@link org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter#setUnauthorizedUrl(String) unauthorizedUrl} =
+ * # (note the above url is null by default, which will cause an HTTP 403 (Access Denied) response instead
+ * # of redirecting to a page. If you want to show a 'nice page' instead, you should specify that url. Many
+ * # applications like to use the same url specified in roles.unauthorizedUrl above.
+ * #
+ * #
+ * # Define your own filters here as you would any other object as described in the '[main]' section above (properties,
+ * # $references, etc). To properly handle url path matching (see the [urls] section below), your
+ * # filter should extend the {@link org.apache.shiro.web.filter.PathMatchingFilter PathMatchingFilter} abstract class.
+ * #
+ * [urls]
+ * # This section defines url path mappings. Each mapping entry must be on a single line and conform to the
+ * # following representation:
+ * #
+ * # ant_path_expression = path_specific_filter_chain_definition
+ * #
+ * # For any request that matches a specified path, the corresponding value defines a comma-delimited chain of
+ * # filters to execute for that request.
+ * #
+ * # This is incredibly powerful in that you can define arbitrary filter chains for any given request pattern
+ * # to greatly customize the security experience.
+ * #
+ * # The path_specific_filter_chain_definition must match the following format:
+ * #
+ * # filter1[optional_config1], filter2[optional_config2], ..., filterN[optional_configN]
+ * #
+ * # where 'filterN' is the name of an filter defined above in the [filters] section and
+ * # '[optional_configN]' is an optional bracketed string that has meaning for that particular filter for
+ * # _that particular path_. If the filter does not need specific config for that url path, you may
+ * # discard the brackets - that is, filterN[] just becomes filterN.
+ * #
+ * # And because filter tokens define chains, order matters! Define the tokens for each path pattern
+ * # in the order you want them to filter (comma-delimited).
+ * #
+ * # Finally, each filter is free to handle the response however it wants if its necessary
+ * # conditions are not met (redirect, HTTP error code, direct rendering, etc). Otherwise, it is expected to allow
+ * # the request to continue through the chain on to the final destination view.
+ * #
+ * # Examples:
+ * #
+ * # To illustrate chain configuration, look at the /account/** mapping below. This says
+ * # "apply the above 'authcBasic' filter to any request matching the '/account/**' pattern". Since the
+ * # 'authcBasic' filter does not need any path-specific config, it doesn't have any config brackets [].
+ * #
+ * # The /remoting/** definition on the other hand uses the 'roles' and 'perms' filters which do use
+ * # bracket notation. That definition says:
+ * #
+ * # "To access /remoting/** urls, ensure that the user is first authenticated ('authcBasic'), then ensure that user
+ * # has the 'b2bClient' role, and then finally ensure that they have the 'remote:invoke:lan,wan' permission."
+ * #
+ * # (Note that because elements within brackets [ ] are comma-delimited themselves, we needed to escape the permission
+ * # actions of 'lan,wan' with quotes. If we didn't do that, the permission filter would interpret
+ * # the text between the brackets as two permissions: 'remote:invoke:lan' and 'wan' instead of the
+ * # single desired 'remote:invoke:lan,wan' token. So, you can use quotes wherever you need to escape internal
+ * # commas.)
+ * #
+ * /account/** = <a href="#authcBasic">authcBasic</a>
+ * /remoting/** = <a href="#authcBasic">authcBasic</a>, <a href="#roles">roles</a>[b2bClient], <a href="#perms">perms</a>[remote:invoke:"lan,wan"]
+ * #
+ * </param-value></init-param>
+ * </filter>
+ * #
+ * #
+ * <filter-mapping>
+ * <filter-name>KiFilter</filter-name>
+ * <url-pattern>/*</url-pattern>
+ * </filter-mapping></pre>
+ *
+ * @author Les Hazlewood
+ * @author Jeremy Haile
+ * @since 0.1
+ */
+public class ShiroFilter extends OncePerRequestFilter {
+
+ //TODO - complete JavaDoc
+
+ public static final String SECURITY_MANAGER_CONTEXT_KEY = SecurityManager.class.getName() + "_SERVLET_CONTEXT_KEY";
+
+ public static final String CONFIG_CLASS_NAME_INIT_PARAM_NAME = "configClassName";
+ public static final String CONFIG_INIT_PARAM_NAME = "config";
+ public static final String CONFIG_URL_INIT_PARAM_NAME = "configUrl";
+
+ private static final Logger log = LoggerFactory.getLogger(ShiroFilter.class);
+
+ protected String config;
+ protected String configUrl;
+ protected String configClassName;
+ protected WebConfiguration configuration;
+
+ // Reference to the security manager used by this filter
+ protected SecurityManager securityManager;
+
+ public ShiroFilter() {
+ this.configClassName = IniWebConfiguration.class.getName();
+ }
+
+ public WebConfiguration getConfiguration() {
+ return configuration;
+ }
+
+ public void setConfiguration(WebConfiguration configuration) {
+ this.configuration = configuration;
+ }
+
+ public SecurityManager getSecurityManager() {
+ return securityManager;
+ }
+
+ protected void setSecurityManager(org.apache.shiro.mgt.SecurityManager sm) {
+ this.securityManager = sm;
+ }
+
+ protected void onFilterConfigSet() throws Exception {
+ applyInitParams();
+ WebConfiguration config = configure();
+ setConfiguration(config);
+
+ // Retrieve and store a reference to the security manager
+ SecurityManager sm = ensureSecurityManager(config);
+ setSecurityManager(sm);
+ }
+
+ /**
+ * Retrieves the security manager for the given configuration.
+ *
+ * @param config the configuration for this filter.
+ * @return the security manager that this filter should use.
+ */
+ protected SecurityManager ensureSecurityManager(Configuration config) {
+ SecurityManager sm = config.getSecurityManager();
+
+ // If the config doesn't return a security manager, build one by default.
+ if (sm == null) {
+ if (log.isInfoEnabled()) {
+ log.info("Configuration instance [" + config + "] did not provide a SecurityManager. No config " +
+ "specified? Defaulting to a " + DefaultWebSecurityManager.class.getName() + " instance...");
+ }
+ sm = new DefaultWebSecurityManager();
+ }
+
+ return sm;
+ }
+
+ protected void applyInitParams() {
+ FilterConfig config = getFilterConfig();
+
+ String configCN = clean(config.getInitParameter(CONFIG_CLASS_NAME_INIT_PARAM_NAME));
+ if (configCN != null) {
+ if (ClassUtils.isAvailable(configCN)) {
+ this.configClassName = configCN;
+ } else {
+ String msg = "configClassName fully qualified class name value [" + configCN + "] is not " +
+ "available in the classpath. Please ensure you have typed it correctly and the " +
+ "corresponding class or jar is in the classpath.";
+ throw new ConfigurationException(msg);
+ }
+ }
+
+ this.config = clean(config.getInitParameter(CONFIG_INIT_PARAM_NAME));
+ this.configUrl = clean(config.getInitParameter(CONFIG_URL_INIT_PARAM_NAME));
+ }
+
+ protected WebConfiguration configure() {
+ WebConfiguration conf = (WebConfiguration) ClassUtils.newInstance(this.configClassName);
+ applyFilterConfig(conf);
+ applyUrlConfig(conf);
+ applyEmbeddedConfig(conf);
+ LifecycleUtils.init(conf);
+ return conf;
+ }
+
+ protected void applyFilterConfig(WebConfiguration conf) {
+ if (log.isDebugEnabled()) {
+ String msg = "Attempting to inject the FilterConfig (using 'setFilterConfig' method) into the " +
+ "instantiated WebConfiguration for any wrapped Filter initialization...";
+ log.debug(msg);
+ }
+ try {
+ PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor(conf, "filterConfig");
+ if (pd != null) {
+ PropertyUtils.setProperty(conf, "filterConfig", getFilterConfig());
+ }
+ } catch (Exception e) {
+ if (log.isDebugEnabled()) {
+ log.debug("Error setting FilterConfig on WebConfiguration instance.", e);
+ }
+ }
+ }
+
+ protected void applyEmbeddedConfig(WebConfiguration conf) {
+ if (this.config != null) {
+ try {
+ PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor(conf, "config");
+
+ if (pd != null) {
+ PropertyUtils.setProperty(conf, "config", this.config);
+ } else {
+ String msg = "The 'config' filter param was specified, but there is no " +
+ "'setConfig(String)' method on the Configuration instance [" + conf + "]. If you do " +
+ "not require the 'config' filter param, please comment it out, or if you do need it, " +
+ "please ensure your Configuration instance has a 'setConfig(String)' method to receive it.";
+ throw new ConfigurationException(msg);
+ }
+ } catch (Exception e) {
+ String msg = "There was an error setting the 'config' property of the Configuration object.";
+ throw new ConfigurationException(msg, e);
+ }
+ }
+ }
+
+ protected void applyUrlConfig(WebConfiguration conf) {
+ if (this.configUrl != null) {
+ try {
+ PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor(conf, "configUrl");
+
+ if (pd != null) {
+ PropertyUtils.setProperty(conf, "configUrl", this.configUrl);
+ } else {
+ String msg = "The 'configUrl' filter param was specified, but there is no " +
+ "'setConfigUrl(String)' method on the Configuration instance [" + conf + "]. If you do " +
+ "not require the 'configUrl' filter param, please comment it out, or if you do need it, " +
+ "please ensure your Configuration instance has a 'setConfigUrl(String)' method to receive it.";
+ throw new ConfigurationException(msg);
+ }
+ } catch (Exception e) {
+ String msg = "There was an error setting the 'configUrl' property of the Configuration object.";
+ throw new ConfigurationException(msg, e);
+ }
+ }
+ }
+
+ protected boolean isHttpSessions() {
+ SecurityManager secMgr = getSecurityManager();
+ return !(secMgr instanceof DefaultWebSecurityManager) || ((DefaultWebSecurityManager) secMgr).isHttpSessionMode();
+ }
+
+ protected InetAddress getInetAddress(ServletRequest request) {
+ return WebUtils.getInetAddress(request);
+ }
+
+ /**
+ * Wraps the original HttpServletRequest in a {@link ShiroHttpServletRequest}, which is required for supporting
+ * Servlet Specification behavior backed by a {@link org.apache.shiro.subject.Subject Subject} instance.
+ *
+ * @param orig the original Servlet Container-provided incoming {@code HttpServletRequest} instance.
+ * @return {@link ShiroHttpServletRequest KiHttpServletRequest} instance wrapping the original.
+ * @since 1.0
+ */
+ protected ServletRequest wrapServletRequest(HttpServletRequest orig) {
+ return new ShiroHttpServletRequest(orig, getServletContext(), isHttpSessions());
+ }
+
+ /**
+ * 'Prepare's the {@code ServletRequest} instance that will be passed to the {@code FilterChain} for request
+ * processing.
+ * <p/>
+ * If the {@code ServletRequest} is an instance of {@link HttpServletRequest}, the value returned from this method
+ * is obtained by calling {@link #wrapServletRequest(javax.servlet.http.HttpServletRequest)} to allow Shiro-specific
+ * HTTP behavior, otherwise the original {@code ServletRequest} argument is returned.
+ *
+ * @param request the incoming ServletRequest
+ * @param response the outgoing ServletResponse
+ * @param chain the Servlet Container provided {@code FilterChain} that will receive the returned request.
+ * @return the {@code ServletRequest} instance that will be passed to the {@code FilterChain} for request processing.
+ * @since 1.0
+ */
+ @SuppressWarnings({"UnusedDeclaration"})
+ protected ServletRequest prepareServletRequest(ServletRequest request, ServletResponse response, FilterChain chain) {
+ ServletRequest toUse = request;
+ if (request instanceof HttpServletRequest) {
+ HttpServletRequest http = (HttpServletRequest) request;
+ toUse = wrapServletRequest(http);
+ }
+ return toUse;
+ }
+
+ /**
+ * Returns a new {@link ShiroHttpServletResponse} instance, wrapping the {@code orig} argument, in order to provide
+ * correct URL rewriting behavior required by the Servlet Specification when using Shiro-based sessions (and not
+ * Servlet Container HTTP-based sessions).
+ *
+ * @param orig the original {@code HttpServletResponse} instance provided by the Servlet Container.
+ * @param request the {@code KiHttpServletRequest} instance wrapping the original request.
+ * @return the wrapped ServletResponse instance to use during {@link FilterChain} execution.
+ * @since 1.0
+ */
+ protected ServletResponse wrapServletResponse(HttpServletResponse orig, ShiroHttpServletRequest request) {
+ return new ShiroHttpServletResponse(orig, getServletContext(), request);
+ }
+
+ /**
+ * 'Prepare's the {@code ServletResponse} instance that will be passed to the {@code FilterChain} for request
+ * processing.
+ * <p/>
+ * This implementation delegates to {@link #wrapServletRequest(javax.servlet.http.HttpServletRequest)}
+ * only if Shiro-based sessions are enabled (that is, !{@link #isHttpSessions()}) and the request instance is a
+ * {@link ShiroHttpServletRequest}. This ensures that any URL rewriting that occurs is handled correctly using the
+ * Shiro-managed Session's sessionId and not a servlet container session ID.
+ * <p/>
+ * If HTTP-based sessions are enabled (the default), then this method does nothing and just returns the
+ * {@code ServletResponse} argument as-is, relying on the default Servlet Container URL rewriting logic.
+ *
+ * @param request the incoming ServletRequest
+ * @param response the outgoing ServletResponse
+ * @param chain the Servlet Container provided {@code FilterChain} that will receive the returned request.
+ * @return the {@code ServletResponse} instance that will be passed to the {@code FilterChain} during request processing.
+ * @since 1.0
+ */
+ @SuppressWarnings({"UnusedDeclaration"})
+ protected ServletResponse prepareServletResponse(ServletRequest request, ServletResponse response, FilterChain chain) {
+ ServletResponse toUse = response;
+ if (!isHttpSessions() && (request instanceof ShiroHttpServletRequest) &&
+ (response instanceof HttpServletResponse)) {
+ //the ShiroHttpServletResponse exists to support URL rewriting for session ids. This is only needed if
+ //using Shiro sessions (i.e. not simple HttpSession based sessions):
+ toUse = wrapServletResponse((HttpServletResponse) response, (ShiroHttpServletRequest) request);
+ }
+ return toUse;
+ }
+
+ /**
+ * Binds the current request/response pair and additional information to a thread-local to be made available to Shiro
+ * during the course of the request/response process. This implementation binds the request/response pair to the
+ * currently executing thread via the {@link ThreadContext}, as well as the Request's
+ * {@link javax.servlet.ServletRequest#getRemoteAddr() remoteAddr} (client InetAddress), the application's
+ * configured {@link SecurityManager}, and sets up and binds the currently executing
+ * {@link org.apache.shiro.subject.Subject Subject} instance to ensure the Subject is available before any request
+ * processing occurs.
+ * <p/>
+ * To guarantee properly cleaned threads in a thread-pooled Servlet Container environment, the corresponding
+ * {@link #unbind} method must be called in a {@code finally} block to ensure that the thread remains clean even
+ * in the event of an exception thrown while processing the request. This class's
+ * {@link #doFilterInternal(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)}
+ * method implement does indeed perform this.
+ *
+ * @param request the incoming ServletRequest
+ * @param response the outgoing ServletResponse
+ * @since 1.0
+ */
+ protected void bind(ServletRequest request, ServletResponse response) {
+ WebUtils.bindInetAddressToThread(request);
+ WebUtils.bind(request);
+ WebUtils.bind(response);
+ ThreadContext.bind(getSecurityManager());
+ ThreadContext.bind(getSecurityManager().getSubject());
+ }
+
+ /**
+ * Unbinds (removes out of scope) the current {@code ServletRequest} and {@link ServletResponse}.
+ * <p/>
+ * This method implementation merely calls {@code ThreadContext}.{@link ThreadContext#clear() clear()} to ensure
+ * that <em>everything</em> that might have been bound to the thread by Shiro has been removed to ensure the underlying
+ * Thread may be safely re-used in a thread-pooled Servlet Container environment.
+ *
+ * @param request the just-processed incoming servlet response - ignored
+ * @param response the just-processed outgoing servlet response - ignored
+ * @since 1.0
+ */
+ @SuppressWarnings({"UnusedDeclaration"})
+ protected void unbind(ServletRequest request, ServletResponse response) {
+ //arguments ignored, just clear the thread:
+ ThreadContext.clear();
+ }
+
+ /**
+ * {@code doFilterInternal} implementation that sets-up, executes, and cleans-up a Shiro-filtered request. It
+ * performs the following ordered operations:
+ * <ol>
+ * <li>{@link #prepareServletRequest(ServletRequest, ServletResponse, FilterChain) Prepares}
+ * the incoming {@code ServletRequest} for use during Shiro's processing</li>
+ * <li>{@link #prepareServletResponse(ServletRequest, ServletResponse, FilterChain) Prepares}
+ * the outgoing {@code ServletResponse} for use during Shiro's processing</li>
+ * <li>{@link #bind(ServletRequest,ServletResponse) Binds} the request/response pair
+ * and associated data to the currently executing thread for use during processing</li>
+ * <li>{@link #executeChain(ServletRequest,ServletResponse,FilterChain) Executes}
+ * the appropriate {@code FilterChain}</li>
+ * <li>{@link #unbind(javax.servlet.ServletRequest, javax.servlet.ServletResponse) Unbinds} the request/response
+ * pair and any other associated data from the thread.
+ * </ul>
+ * <p/>
+ * The {@link #unbind(javax.servlet.ServletRequest, javax.servlet.ServletResponse) unbind} method is called in a
+ * {@code finally} block to guarantee the thread may be cleanly re-used in a thread-pooled Servlet Container
+ * environment.
+ *
+ * @param servletRequest the incoming {@code ServletRequest}
+ * @param servletResponse the outgoing {@code ServletResponse}
+ * @param chain the container-provided {@code FilterChain} to execute
+ * @throws ServletException if an error occurs
+ * @throws IOException if an IO error occurs
+ */
+ protected void doFilterInternal(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
+ throws ServletException, IOException {
+
+ ServletRequest request = prepareServletRequest(servletRequest, servletResponse, chain);
+ ServletResponse response = prepareServletResponse(request, servletResponse, chain);
+
+ bind(request, response);
+
+ try {
+ executeChain(request, response, chain);
+ } finally {
+ unbind(request, response);
+ }
+ }
+
+ /**
+ * Returns the {@code FilterChain} to execute for the given request.
+ * <p/>
+ * The {@code origChain} argument is the
+ * original {@code FilterChain} supplied by the Servlet Container, but it may be modified to provide
+ * more behavior by appending further chains according to the Shiro configuration.
+ * <p/>
+ * This implementation returns the chain that will actually be executed by acquiring the chain from a
+ * <code>{@link #getConfiguration() getConfiguration()}.{@link org.apache.shiro.web.config.WebConfiguration#getChain getChain}(request,response,origChain)</code>
+ * method call. The configuration itself determines which chain to execute, typically based on URL configuration.
+ * If no chain is returned from this method call (returns {@code null}), then the {@code origChain}
+ * will be returned by default.
+ *
+ * @param request the incoming ServletRequest
+ * @param response the outgoing ServletResponse
+ * @param origChain the original {@code FilterChain} provided by the Servlet Container
+ * @return the {@link FilterChain} to execute for the given request
+ * @since 1.0
+ */
+ protected FilterChain getExecutionChain(ServletRequest request, ServletResponse response, FilterChain origChain) {
+ FilterChain chain = getConfiguration().getChain(request, response, origChain);
+ if (chain == null) {
+ chain = origChain;
+ log.trace("No security filter chain configured for the current request. Using default.");
+ } else {
+ log.trace(" Using configured filter chain for the current request.");
+ }
+ return chain;
+ }
+
+ /**
+ * Executes a {@link FilterChain} for the given request.
+ * <p/>
+ * This implementation first delegates to
+ * <code>{@link #getExecutionChain(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) getExecutionChain}</code>
+ * to allow the application's Shiro configuration to determine exactly how the chain should execute. The resulting
+ * value from that call is then executed directly by calling the returned {@code FilterChain}'s
+ * {@link FilterChain#doFilter doFilter} method. That is:
+ * <p/>
+ * <pre>
+ * FilterChain chain = {@link #getExecutionChain}(request, response, origChain);
+ * chain.{@link FilterChain#doFilter doFilter}(request,response);</pre>
+ *
+ * @param request the incoming ServletRequest
+ * @param response the outgoing ServletResponse
+ * @param origChain the Servlet Container-provided chain that may be wrapped further by an application-configured
+ * chain of Filters.
+ * @throws IOException if the underlying {@code chain.doFilter} call results in an IOException
+ * @throws ServletException if the underlying {@code chain.doFilter} call results in a ServletException
+ * @since 1.0
+ */
+ protected void executeChain(ServletRequest request, ServletResponse response, FilterChain origChain)
+ throws IOException, ServletException {
+ FilterChain chain = getExecutionChain(request, response, origChain);
+ chain.doFilter(request, response);
+ }
+
+ /**
+ * Destroys this Filter by destroying the {@link #getConfiguration() configuration} object.
+ */
+ public void destroy() {
+ LifecycleUtils.destroy(getConfiguration());
+ }
+}
Added: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpServletRequest.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpServletRequest.java?rev=785881&view=auto
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpServletRequest.java (added)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpServletRequest.java Thu Jun 18 03:13:34 2009
@@ -0,0 +1,240 @@
+/*
+ * 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.web.servlet;
+
+import java.security.Principal;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpSession;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.subject.Subject;
+
+
+/**
+ * TODO class JavaDoc
+ *
+ * @author Les Hazlewood
+ * @since 0.2
+ */
+@SuppressWarnings({"deprecated", "deprecation"})
+public class ShiroHttpServletRequest extends HttpServletRequestWrapper {
+
+ //TODO - complete JavaDoc
+
+ //The following 7 constants support the Shiro's implementation of the Servlet Specification
+ public static final String COOKIE_SESSION_ID_SOURCE = "cookie";
+ public static final String URL_SESSION_ID_SOURCE = "url";
+ public static final String REFERENCED_SESSION_ID = ShiroHttpServletRequest.class.getName() + "_REQUESTED_SESSION_ID";
+ public static final String REFERENCED_SESSION_ID_IS_VALID = ShiroHttpServletRequest.class.getName() + "_REQUESTED_SESSION_ID_VALID";
+ public static final String REFERENCED_SESSION_IS_NEW = ShiroHttpServletRequest.class.getName() + "_REFERENCED_SESSION_IS_NEW";
+ public static final String REFERENCED_SESSION_ID_SOURCE = ShiroHttpServletRequest.class.getName() + "REFERENCED_SESSION_ID_SOURCE";
+ public static final String SESSION_ID_NAME = ShiroHttpSession.DEFAULT_SESSION_ID_NAME;
+ /**
+ * Key that may be used to alert that the request's referenced Shiro Session has expired prior to
+ * request processing.
+ */
+ public static final String EXPIRED_SESSION_KEY = ShiroHttpServletRequest.class.getName() + "_EXPIRED_SESSION_KEY";
+
+ public static final String IDENTITY_REMOVED_KEY = ShiroHttpServletRequest.class.getName() + "_IDENTITY_REMOVED_KEY";
+
+ protected ServletContext servletContext = null;
+
+ protected HttpSession session = null;
+ protected boolean httpSessions = true;
+
+ public ShiroHttpServletRequest(HttpServletRequest wrapped, ServletContext servletContext,
+ boolean httpSessions) {
+ super(wrapped);
+ this.servletContext = servletContext;
+ this.httpSessions = httpSessions;
+ }
+
+ public boolean isHttpSessions() {
+ return httpSessions;
+ }
+
+ protected boolean isLoggedOut() {
+ Boolean loggedOut = (Boolean)getAttribute(IDENTITY_REMOVED_KEY);
+ return loggedOut != null && loggedOut;
+ }
+
+ public String getRemoteUser() {
+ String remoteUser;
+ Object scPrincipal = getSubjectPrincipal();
+ if (scPrincipal != null) {
+ if (scPrincipal instanceof String) {
+ return (String) scPrincipal;
+ } else if (scPrincipal instanceof Principal) {
+ remoteUser = ((Principal) scPrincipal).getName();
+ } else {
+ remoteUser = scPrincipal.toString();
+ }
+ } else {
+ remoteUser = super.getRemoteUser();
+ }
+ return remoteUser;
+ }
+
+ protected Subject getSubject() {
+ return SecurityUtils.getSubject();
+ }
+
+ protected Object getSubjectPrincipal() {
+ Object userPrincipal = null;
+ Subject subject = getSubject();
+ if (subject != null) {
+ userPrincipal = subject.getPrincipal();
+ }
+ return userPrincipal;
+ }
+
+ public boolean isUserInRole(String s) {
+ Subject subject = getSubject();
+ boolean inRole = (subject != null && subject.hasRole(s));
+ if (!inRole) {
+ inRole = super.isUserInRole(s);
+ }
+ return inRole;
+ }
+
+ public Principal getUserPrincipal() {
+ Principal userPrincipal;
+ Object scPrincipal = getSubjectPrincipal();
+ if (scPrincipal != null) {
+ if (scPrincipal instanceof Principal) {
+ userPrincipal = (Principal) scPrincipal;
+ } else {
+ userPrincipal = new ObjectPrincipal(scPrincipal);
+ }
+ } else {
+ userPrincipal = super.getUserPrincipal();
+ }
+ return userPrincipal;
+ }
+
+ public String getRequestedSessionId() {
+ String requestedSessionId = null;
+ if (isHttpSessions()) {
+ requestedSessionId = super.getRequestedSessionId();
+ } else {
+ Object sessionId = getAttribute(REFERENCED_SESSION_ID);
+ if (sessionId != null) {
+ requestedSessionId = sessionId.toString();
+ }
+ }
+
+ return requestedSessionId;
+ }
+
+ public HttpSession getSession(boolean create) {
+
+ HttpSession httpSession;
+
+ if (isHttpSessions()) {
+ httpSession = super.getSession(create);
+ } else {
+ if (this.session == null) {
+
+ boolean existing = getSubject().getSession(false) != null;
+
+ Session jsecSession = getSubject().getSession(create);
+ if (jsecSession != null) {
+ this.session = new ShiroHttpSession(jsecSession, this, this.servletContext);
+ if (!existing) {
+ setAttribute(REFERENCED_SESSION_IS_NEW, Boolean.TRUE);
+ }
+ }
+ }
+ httpSession = this.session;
+ }
+
+ return httpSession;
+ }
+
+
+ public HttpSession getSession() {
+ return getSession(true);
+ }
+
+ public boolean isRequestedSessionIdValid() {
+ if (isHttpSessions()) {
+ return super.isRequestedSessionIdValid();
+ } else {
+ Boolean value = (Boolean) getAttribute(REFERENCED_SESSION_ID_IS_VALID);
+ return (value != null && value.equals(Boolean.TRUE));
+ }
+ }
+
+ public boolean isRequestedSessionIdFromCookie() {
+ if (isHttpSessions()) {
+ return super.isRequestedSessionIdFromCookie();
+ } else {
+ String value = (String) getAttribute(REFERENCED_SESSION_ID_SOURCE);
+ return value != null && value.equals(COOKIE_SESSION_ID_SOURCE);
+ }
+ }
+
+ public boolean isRequestedSessionIdFromURL() {
+ if (isHttpSessions()) {
+ return super.isRequestedSessionIdFromURL();
+ } else {
+ String value = (String) getAttribute(REFERENCED_SESSION_ID_SOURCE);
+ return value != null && value.equals(URL_SESSION_ID_SOURCE);
+ }
+ }
+
+ public boolean isRequestedSessionIdFromUrl() {
+ return isRequestedSessionIdFromURL();
+ }
+
+ private class ObjectPrincipal implements java.security.Principal {
+ private Object object = null;
+
+ public ObjectPrincipal(Object object) {
+ this.object = object;
+ }
+
+ public Object getObject() {
+ return object;
+ }
+
+ public String getName() {
+ return getObject().toString();
+ }
+
+ public int hashCode() {
+ return object.hashCode();
+ }
+
+ public boolean equals(Object o) {
+ if (o instanceof ObjectPrincipal) {
+ ObjectPrincipal op = (ObjectPrincipal) o;
+ return getObject().equals(op.getObject());
+ }
+ return false;
+ }
+
+ public String toString() {
+ return object.toString();
+ }
+ }
+}
Added: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpServletResponse.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpServletResponse.java?rev=785881&view=auto
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpServletResponse.java (added)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpServletResponse.java Thu Jun 18 03:13:34 2009
@@ -0,0 +1,317 @@
+/*
+ * 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.web.servlet;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLEncoder;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+import javax.servlet.http.HttpSession;
+
+/**
+ * HttpServletResponse implementation to support URL Encoding of Shiro Session IDs.
+ *
+ * It is only used when using Shiro's native Session Management configuration (and not when using the Servlet
+ * Container session configuration, which is Shiro's default in a web environment). Because the servlet container
+ * already performs url encoding of its own session ids, instances of this class are only needed when using Shiro
+ * native sessions.
+ *
+ * <p>Note that this implementation relies in part on source code from the Tomcat 6.x distribution for
+ * encoding URLs for session ID URL Rewriting (we didn't want to re-invent the wheel). Since Shiro is also
+ * Apache 2.0 license, all regular licenses and conditions have remained in tact.
+ *
+ * @author Les Hazlewood
+ * @since 0.2
+ */
+@SuppressWarnings({"deprecated", "deprecation"})
+public class ShiroHttpServletResponse extends HttpServletResponseWrapper {
+
+ //TODO - complete JavaDoc
+
+ private static final String DEFAULT_SESSION_ID_PARAMETER_NAME = ShiroHttpSession.DEFAULT_SESSION_ID_NAME;
+
+ private ServletContext context = null;
+ //the associated request
+ private ShiroHttpServletRequest request = null;
+
+ public ShiroHttpServletResponse(HttpServletResponse wrapped, ServletContext context, ShiroHttpServletRequest request) {
+ super(wrapped);
+ this.context = context;
+ this.request = request;
+ }
+
+ public ServletContext getContext() {
+ return context;
+ }
+
+ public void setContext(ServletContext context) {
+ this.context = context;
+ }
+
+ public ShiroHttpServletRequest getRequest() {
+ return request;
+ }
+
+ public void setRequest(ShiroHttpServletRequest request) {
+ this.request = request;
+ }
+
+ /**
+ * Encode the session identifier associated with this response
+ * into the specified redirect URL, if necessary.
+ *
+ * @param url URL to be encoded
+ */
+ public String encodeRedirectURL(String url) {
+ if (isEncodeable(toAbsolute(url))) {
+ return toEncoded(url, request.getSession().getId());
+ } else {
+ return url;
+ }
+ }
+
+
+ public String encodeRedirectUrl(String s) {
+ return encodeRedirectURL(s);
+ }
+
+
+ /**
+ * Encode the session identifier associated with this response
+ * into the specified URL, if necessary.
+ *
+ * @param url URL to be encoded
+ */
+ public String encodeURL(String url) {
+ String absolute = toAbsolute(url);
+ if (isEncodeable(absolute)) {
+ // W3c spec clearly said
+ if (url.equalsIgnoreCase("")) {
+ url = absolute;
+ }
+ return toEncoded(url, request.getSession().getId());
+ } else {
+ return url;
+ }
+ }
+
+ public String encodeUrl(String s) {
+ return encodeURL(s);
+ }
+
+ /**
+ * Return <code>true</code> if the specified URL should be encoded with
+ * a session identifier. This will be true if all of the following
+ * conditions are met:
+ * <ul>
+ * <li>The request we are responding to asked for a valid session
+ * <li>The requested session ID was not received via a cookie
+ * <li>The specified URL points back to somewhere within the web
+ * application that is responding to this request
+ * </ul>
+ *
+ * @param location Absolute URL to be validated
+ */
+ protected boolean isEncodeable(final String location) {
+
+ if (location == null)
+ return (false);
+
+ // Is this an intra-document reference?
+ if (location.startsWith("#"))
+ return (false);
+
+ // Are we in a valid session that is not using cookies?
+ final HttpServletRequest hreq = request;
+ final HttpSession session = hreq.getSession(false);
+ if (session == null)
+ return (false);
+ if (hreq.isRequestedSessionIdFromCookie())
+ return (false);
+
+ return doIsEncodeable(hreq, session, location);
+ }
+
+ private boolean doIsEncodeable(HttpServletRequest hreq, HttpSession session, String location) {
+ // Is this a valid absolute URL?
+ URL url = null;
+ try {
+ url = new URL(location);
+ } catch (MalformedURLException e) {
+ return (false);
+ }
+
+ // Does this URL match down to (and including) the context path?
+ if (!hreq.getScheme().equalsIgnoreCase(url.getProtocol()))
+ return (false);
+ if (!hreq.getServerName().equalsIgnoreCase(url.getHost()))
+ return (false);
+ int serverPort = hreq.getServerPort();
+ if (serverPort == -1) {
+ if ("https".equals(hreq.getScheme()))
+ serverPort = 443;
+ else
+ serverPort = 80;
+ }
+ int urlPort = url.getPort();
+ if (urlPort == -1) {
+ if ("https".equals(url.getProtocol()))
+ urlPort = 443;
+ else
+ urlPort = 80;
+ }
+ if (serverPort != urlPort)
+ return (false);
+
+ String contextPath = getRequest().getContextPath();
+ if (contextPath != null) {
+ String file = url.getFile();
+ if ((file == null) || !file.startsWith(contextPath))
+ return (false);
+ String tok = ";" + DEFAULT_SESSION_ID_PARAMETER_NAME + "=" + session.getId();
+ if (file.indexOf(tok, contextPath.length()) >= 0)
+ return (false);
+ }
+
+ // This URL belongs to our web application, so it is encodeable
+ return (true);
+
+ }
+
+
+ /**
+ * Convert (if necessary) and return the absolute URL that represents the
+ * resource referenced by this possibly relative URL. If this URL is
+ * already absolute, return it unchanged.
+ *
+ * @param location URL to be (possibly) converted and then returned
+ * @throws IllegalArgumentException if a MalformedURLException is
+ * thrown when converting the relative URL to an absolute one
+ */
+ private String toAbsolute(String location) {
+
+ if (location == null)
+ return (location);
+
+ boolean leadingSlash = location.startsWith("/");
+
+ if (leadingSlash || !hasScheme(location)) {
+
+ StringBuffer buf = new StringBuffer();
+
+ String scheme = request.getScheme();
+ String name = request.getServerName();
+ int port = request.getServerPort();
+
+ try {
+ buf.append(scheme).append("://").append(name);
+ if ((scheme.equals("http") && port != 80)
+ || (scheme.equals("https") && port != 443)) {
+ buf.append(':').append(port);
+ }
+ if (!leadingSlash) {
+ String relativePath = request.getRequestURI();
+ int pos = relativePath.lastIndexOf('/');
+ relativePath = relativePath.substring(0, pos);
+
+ String encodedURI = URLEncoder.encode(relativePath, getCharacterEncoding());
+ buf.append(encodedURI).append('/');
+ }
+ buf.append(location);
+ } catch (IOException e) {
+ IllegalArgumentException iae = new IllegalArgumentException(location);
+ iae.initCause(e);
+ throw iae;
+ }
+
+ return buf.toString();
+
+ } else {
+ return location;
+ }
+ }
+
+ /**
+ * Determine if the character is allowed in the scheme of a URI.
+ * See RFC 2396, Section 3.1
+ */
+ public static boolean isSchemeChar(char c) {
+ return Character.isLetterOrDigit(c) ||
+ c == '+' || c == '-' || c == '.';
+ }
+
+
+ /**
+ * Determine if a URI string has a <code>scheme</code> component.
+ */
+ private boolean hasScheme(String uri) {
+ int len = uri.length();
+ for (int i = 0; i < len; i++) {
+ char c = uri.charAt(i);
+ if (c == ':') {
+ return i > 0;
+ } else if (!isSchemeChar(c)) {
+ return false;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return the specified URL with the specified session identifier
+ * suitably encoded.
+ *
+ * @param url URL to be encoded with the session id
+ * @param sessionId Session id to be included in the encoded URL
+ */
+ protected String toEncoded(String url, String sessionId) {
+
+ if ((url == null) || (sessionId == null))
+ return (url);
+
+ String path = url;
+ String query = "";
+ String anchor = "";
+ int question = url.indexOf('?');
+ if (question >= 0) {
+ path = url.substring(0, question);
+ query = url.substring(question);
+ }
+ int pound = path.indexOf('#');
+ if (pound >= 0) {
+ anchor = path.substring(pound);
+ path = path.substring(0, pound);
+ }
+ StringBuffer sb = new StringBuffer(path);
+ if (sb.length() > 0) { // jsessionid can't be first.
+ sb.append(";");
+ sb.append(DEFAULT_SESSION_ID_PARAMETER_NAME);
+ sb.append("=");
+ sb.append(sessionId);
+ }
+ sb.append(anchor);
+ sb.append(query);
+ return (sb.toString());
+
+ }
+}
Added: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpSession.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpSession.java?rev=785881&view=auto
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpSession.java (added)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpSession.java Thu Jun 18 03:13:34 2009
@@ -0,0 +1,248 @@
+/*
+ * 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.web.servlet;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionBindingListener;
+import javax.servlet.http.HttpSessionContext;
+
+import org.apache.shiro.session.InvalidSessionException;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.web.session.WebSession;
+
+
+/**
+ * Wrapper class that uses a Shiro session under the hood for all session operations instead of the
+ * Servlet Container's session mechanism. This is preferred in heterogeneous client environments where the Session
+ * is used on both the business tier as well as in multiple client technologies (web, swing, flash, etc).
+ *
+ * @author Les Hazlewood
+ * @since 0.2
+ */
+@SuppressWarnings({"deprecation"})
+public class ShiroHttpSession implements HttpSession {
+
+ //TODO - complete JavaDoc
+
+ public static final String DEFAULT_SESSION_ID_NAME = "JSESSIONID";
+
+ private static final Enumeration EMPTY_ENUMERATION = new Enumeration() {
+ public boolean hasMoreElements() {
+ return false;
+ }
+
+ public Object nextElement() {
+ return null;
+ }
+ };
+
+ private static final HttpSessionContext HTTP_SESSION_CONTEXT = new HttpSessionContext() {
+ public HttpSession getSession(String s) {
+ return null;
+ }
+
+ public Enumeration getIds() {
+ return EMPTY_ENUMERATION;
+ }
+ };
+
+ protected ServletContext servletContext = null;
+ protected HttpServletRequest currentRequest = null;
+ protected Session session = null; //'real' Shiro Session
+
+ public ShiroHttpSession(Session session, HttpServletRequest currentRequest, ServletContext servletContext) {
+ if (session instanceof WebSession) {
+ String msg = "Session constructor argument cannot be an instance of WebSession. This is enforced to " +
+ "prevent circular dependencies and infinite loops.";
+ throw new IllegalArgumentException(msg);
+ }
+ this.session = session;
+ this.currentRequest = currentRequest;
+ this.servletContext = servletContext;
+ }
+
+ public Session getSession() {
+ return this.session;
+ }
+
+ public long getCreationTime() {
+ try {
+ return getSession().getStartTimestamp().getTime();
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public String getId() {
+ return getSession().getId().toString();
+ }
+
+ public long getLastAccessedTime() {
+ return getSession().getLastAccessTime().getTime();
+ }
+
+ public ServletContext getServletContext() {
+ return this.servletContext;
+ }
+
+ public void setMaxInactiveInterval(int i) {
+ try {
+ getSession().setTimeout(i * 1000);
+ } catch (InvalidSessionException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public int getMaxInactiveInterval() {
+ try {
+ return (new Long(getSession().getTimeout() / 1000)).intValue();
+ } catch (InvalidSessionException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public HttpSessionContext getSessionContext() {
+ return HTTP_SESSION_CONTEXT;
+ }
+
+ public Object getAttribute(String s) {
+ try {
+ return getSession().getAttribute(s);
+ } catch (InvalidSessionException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public Object getValue(String s) {
+ return getAttribute(s);
+ }
+
+ @SuppressWarnings({"unchecked"})
+ protected Set<String> getKeyNames() {
+ Collection<Object> keySet;
+ try {
+ keySet = getSession().getAttributeKeys();
+ } catch (InvalidSessionException e) {
+ throw new IllegalStateException(e);
+ }
+ Set<String> keyNames;
+ if (keySet != null && !keySet.isEmpty()) {
+ keyNames = new HashSet<String>(keySet.size());
+ for (Object o : keySet) {
+ keyNames.add(o.toString());
+ }
+ } else {
+ keyNames = Collections.EMPTY_SET;
+ }
+ return keyNames;
+ }
+
+ public Enumeration getAttributeNames() {
+ Set<String> keyNames = getKeyNames();
+ final Iterator iterator = keyNames.iterator();
+ return new Enumeration() {
+ public boolean hasMoreElements() {
+ return iterator.hasNext();
+ }
+
+ public Object nextElement() {
+ return iterator.next();
+ }
+ };
+ }
+
+ public String[] getValueNames() {
+ Set<String> keyNames = getKeyNames();
+ String[] array = new String[keyNames.size()];
+ if (keyNames.size() > 0) {
+ array = keyNames.toArray(array);
+ }
+ return array;
+ }
+
+ protected void afterBound(String s, Object o) {
+ if (o instanceof HttpSessionBindingListener) {
+ HttpSessionBindingListener listener = (HttpSessionBindingListener) o;
+ HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, s, o);
+ listener.valueBound(event);
+ }
+ }
+
+ protected void afterUnbound(String s, Object o) {
+ if (o instanceof HttpSessionBindingListener) {
+ HttpSessionBindingListener listener = (HttpSessionBindingListener) o;
+ HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, s, o);
+ listener.valueUnbound(event);
+ }
+ }
+
+ public void setAttribute(String s, Object o) {
+ try {
+ getSession().setAttribute(s, o);
+ afterBound(s, o);
+ } catch (InvalidSessionException e) {
+ //noinspection finally
+ try {
+ afterUnbound(s, o);
+ } finally {
+ //noinspection ThrowFromFinallyBlock
+ throw new IllegalStateException(e);
+ }
+ }
+ }
+
+ public void putValue(String s, Object o) {
+ setAttribute(s, o);
+ }
+
+ public void removeAttribute(String s) {
+ try {
+ Object attribute = getSession().removeAttribute(s);
+ afterUnbound(s, attribute);
+ } catch (InvalidSessionException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public void removeValue(String s) {
+ removeAttribute(s);
+ }
+
+ public void invalidate() {
+ try {
+ getSession().stop();
+ } catch (InvalidSessionException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public boolean isNew() {
+ Boolean value = (Boolean) currentRequest.getAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_IS_NEW);
+ return value != null && value.equals(Boolean.TRUE);
+ }
+}
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/package-info.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/package-info.java?rev=785881&r1=785781&r2=785881&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/package-info.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/package-info.java Thu Jun 18 03:13:34 2009
@@ -1,23 +1,23 @@
-/*
- * 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.
- */
-/**
- * Support implementations that depend heavily on the <tt>javax.servlet.*</tt> API and are meant to be
- * directly used in web.xml (Servlet Filters, Servlet Context Listeners, Servlets, etc)
- */
-package org.apache.ki.web.servlet;
+/*
+ * 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.
+ */
+/**
+ * Support implementations that depend heavily on the <tt>javax.servlet.*</tt> API and are meant to be
+ * directly used in web.xml (Servlet Filters, Servlet Context Listeners, Servlets, etc)
+ */
+package org.apache.shiro.web.servlet;
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java?rev=785881&r1=785781&r2=785881&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java Thu Jun 18 03:13:34 2009
@@ -16,19 +16,19 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.ki.web.session;
+package org.apache.shiro.web.session;
-import org.apache.ki.authz.AuthorizationException;
-import org.apache.ki.authz.HostUnauthorizedException;
-import org.apache.ki.session.InvalidSessionException;
-import org.apache.ki.session.Session;
-import org.apache.ki.session.mgt.DefaultSessionManager;
-import org.apache.ki.web.WebUtils;
-import org.apache.ki.web.attr.CookieAttribute;
-import org.apache.ki.web.attr.RequestParamAttribute;
-import org.apache.ki.web.attr.WebAttribute;
-import org.apache.ki.web.servlet.KiHttpServletRequest;
-import org.apache.ki.web.servlet.KiHttpSession;
+import org.apache.shiro.authz.AuthorizationException;
+import org.apache.shiro.authz.HostUnauthorizedException;
+import org.apache.shiro.session.InvalidSessionException;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.session.mgt.DefaultSessionManager;
+import org.apache.shiro.web.WebUtils;
+import org.apache.shiro.web.attr.CookieAttribute;
+import org.apache.shiro.web.attr.RequestParamAttribute;
+import org.apache.shiro.web.attr.WebAttribute;
+import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
+import org.apache.shiro.web.servlet.ShiroHttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -152,7 +152,7 @@
protected void ensureCookieSessionIdStore() {
CookieAttribute<Serializable> cookieStore = getSessionIdCookieAttribute();
if (cookieStore == null) {
- cookieStore = new CookieAttribute<Serializable>(KiHttpSession.DEFAULT_SESSION_ID_NAME);
+ cookieStore = new CookieAttribute<Serializable>(ShiroHttpSession.DEFAULT_SESSION_ID_NAME);
cookieStore.setCheckRequestParams(false);
setSessionIdCookieAttribute(cookieStore);
}
@@ -161,7 +161,7 @@
protected void ensureRequestParamSessionIdStore() {
RequestParamAttribute<Serializable> reqParamStore = getSessionIdRequestParamAttribute();
if (reqParamStore == null) {
- reqParamStore = new RequestParamAttribute<Serializable>(KiHttpSession.DEFAULT_SESSION_ID_NAME);
+ reqParamStore = new RequestParamAttribute<Serializable>(ShiroHttpSession.DEFAULT_SESSION_ID_NAME);
setSessionIdRequestParamAttribute(reqParamStore);
}
}
@@ -213,7 +213,7 @@
}
private void markSessionIdValid(Serializable sessionId, ServletRequest request) {
- request.setAttribute(KiHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
+ request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
}
private void removeSessionIdCookie(ServletRequest request, ServletResponse response) {
@@ -225,17 +225,17 @@
WebAttribute<Serializable> cookieSessionIdAttribute = getSessionIdCookieAttribute();
Serializable id = cookieSessionIdAttribute.retrieveValue(request, response);
if (id != null) {
- request.setAttribute(KiHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,
- KiHttpServletRequest.COOKIE_SESSION_ID_SOURCE);
+ request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,
+ ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE);
} else {
id = getSessionIdRequestParamAttribute().retrieveValue(request, response);
if (id != null) {
- request.setAttribute(KiHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,
- KiHttpServletRequest.URL_SESSION_ID_SOURCE);
+ request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,
+ ShiroHttpServletRequest.URL_SESSION_ID_SOURCE);
}
}
if (id != null) {
- request.setAttribute(KiHttpServletRequest.REFERENCED_SESSION_ID, id);
+ request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);
}
return id;
}
@@ -259,8 +259,8 @@
}
protected void onSessionStart(ServletRequest request) {
- request.removeAttribute(KiHttpServletRequest.REFERENCED_SESSION_ID_SOURCE);
- request.setAttribute(KiHttpServletRequest.REFERENCED_SESSION_IS_NEW, Boolean.TRUE);
+ request.removeAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE);
+ request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_IS_NEW, Boolean.TRUE);
}
@Override
@@ -280,7 +280,7 @@
* @param request incoming servlet request
* @param response outgoing servlet response
* @return the Session associated with the incoming request or <tt>null</tt> if one does not exist.
- * @throws org.apache.ki.authz.AuthorizationException
+ * @throws org.apache.shiro.authz.AuthorizationException
* if the caller is not authorized to access the session associated with the request.
*/
public Session getSession(ServletRequest request, ServletResponse response)
@@ -290,7 +290,7 @@
Serializable sessionId = getReferencedSessionId(request, response);
if (sessionId != null) {
- request.setAttribute(KiHttpServletRequest.REFERENCED_SESSION_ID, sessionId);
+ request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, sessionId);
try {
session = retrieveSessionFromDataSource(sessionId);
markSessionIdValid(sessionId, request);
@@ -311,7 +311,7 @@
}
} else {
if (log.isTraceEnabled()) {
- log.trace("A valid Ki session id was not associated with the current request.");
+ log.trace("A valid Shiro session id was not associated with the current request.");
}
}
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/ServletContainerSessionManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/ServletContainerSessionManager.java?rev=785881&r1=785781&r2=785881&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/ServletContainerSessionManager.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/ServletContainerSessionManager.java Thu Jun 18 03:13:34 2009
@@ -16,14 +16,14 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.ki.web.session;
+package org.apache.shiro.web.session;
-import org.apache.ki.authz.AuthorizationException;
-import org.apache.ki.session.InvalidSessionException;
-import org.apache.ki.session.Session;
-import org.apache.ki.session.mgt.AbstractSessionManager;
-import org.apache.ki.session.mgt.SessionFactory;
-import org.apache.ki.web.WebUtils;
+import org.apache.shiro.authz.AuthorizationException;
+import org.apache.shiro.session.InvalidSessionException;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.session.mgt.AbstractSessionManager;
+import org.apache.shiro.session.mgt.SessionFactory;
+import org.apache.shiro.web.WebUtils;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
@@ -39,8 +39,8 @@
* Servlet container's HttpSession.
* <p/>
* Despite its name, this implementation <em>does not</em> itself manage Sessions since the Servlet container
- * provides the actual management support. This class mainly exists to 'impersonate' a regular Ki
- * <tt>SessionManager</tt> so it can be pluggable into a normal Ki configuration in a pure web application.
+ * provides the actual management support. This class mainly exists to 'impersonate' a regular Shiro
+ * <tt>SessionManager</tt> so it can be pluggable into a normal Shiro configuration in a pure web application.
* <p/>
* Note that because this implementation relies on the {@link HttpSession HttpSession}, it is only functional in a
* servlet container. I.e. it is <em>NOT</em> capable of supporting Sessions any clients other than
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSession.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSession.java?rev=785881&r1=785781&r2=785881&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSession.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSession.java Thu Jun 18 03:13:34 2009
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.ki.web.session;
+package org.apache.shiro.web.session;
import java.io.Serializable;
import java.net.InetAddress;
@@ -26,9 +26,10 @@
import java.util.Enumeration;
import javax.servlet.http.HttpSession;
-import org.apache.ki.session.InvalidSessionException;
-import org.apache.ki.session.Session;
-import org.apache.ki.web.servlet.KiHttpSession;
+import org.apache.shiro.session.InvalidSessionException;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.web.servlet.ShiroHttpSession;
+
/**
* TODO class JavaDoc
@@ -50,8 +51,8 @@
String msg = "HttpSession constructor argument cannot be null.";
throw new IllegalArgumentException(msg);
}
- if (httpSession instanceof KiHttpSession) {
- String msg = "HttpSession constructor argument cannot be an instance of KiHttpSession. This " +
+ if (httpSession instanceof ShiroHttpSession) {
+ String msg = "HttpSession constructor argument cannot be an instance of ShiroHttpSession. This " +
"is enforced to prevent circular dependencies and infinite loops.";
throw new IllegalArgumentException(msg);
}
@@ -134,7 +135,7 @@
private static String assertString(Object key) {
if (!(key instanceof String)) {
- String msg = "HttpSession based implementations of the Ki Session interface requires attribute keys " +
+ String msg = "HttpSession based implementations of the Shiro Session interface requires attribute keys " +
"to be String objects. The HttpSession class does not support anything other than String keys.";
throw new IllegalArgumentException(msg);
}
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionManager.java?rev=785881&r1=785781&r2=785881&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionManager.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionManager.java Thu Jun 18 03:13:34 2009
@@ -16,13 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.ki.web.session;
+package org.apache.shiro.web.session;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
-import org.apache.ki.session.Session;
-import org.apache.ki.session.mgt.SessionManager;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.session.mgt.SessionManager;
/**
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/package-info.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/package-info.java?rev=785881&r1=785781&r2=785881&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/package-info.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/package-info.java Thu Jun 18 03:13:34 2009
@@ -1,22 +1,22 @@
-/*
- * 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.
- */
-/**
- * Components supporting Session management in web-enabled applications.
- */
-package org.apache.ki.web.session;
+/*
+ * 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.
+ */
+/**
+ * Components supporting Session management in web-enabled applications.
+ */
+package org.apache.shiro.web.session;
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/AuthenticatedTag.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/AuthenticatedTag.java?rev=785881&r1=785781&r2=785881&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/AuthenticatedTag.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/AuthenticatedTag.java Thu Jun 18 03:13:34 2009
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.ki.web.tags;
+package org.apache.shiro.web.tags;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/GuestTag.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/GuestTag.java?rev=785881&r1=785781&r2=785881&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/GuestTag.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/GuestTag.java Thu Jun 18 03:13:34 2009
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.ki.web.tags;
+package org.apache.shiro.web.tags;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/HasAnyRolesTag.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/HasAnyRolesTag.java?rev=785881&r1=785781&r2=785881&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/HasAnyRolesTag.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/HasAnyRolesTag.java Thu Jun 18 03:13:34 2009
@@ -16,9 +16,9 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.ki.web.tags;
+package org.apache.shiro.web.tags;
-import org.apache.ki.subject.Subject;
+import org.apache.shiro.subject.Subject;
/**
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/HasPermissionTag.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/HasPermissionTag.java?rev=785881&r1=785781&r2=785881&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/HasPermissionTag.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/HasPermissionTag.java Thu Jun 18 03:13:34 2009
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.ki.web.tags;
+package org.apache.shiro.web.tags;
/**
* @author Les Hazlewood
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/HasRoleTag.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/HasRoleTag.java?rev=785881&r1=785781&r2=785881&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/HasRoleTag.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/HasRoleTag.java Thu Jun 18 03:13:34 2009
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.ki.web.tags;
+package org.apache.shiro.web.tags;
/**
* @author Les Hazlewood
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/LacksPermissionTag.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/LacksPermissionTag.java?rev=785881&r1=785781&r2=785881&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/LacksPermissionTag.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/LacksPermissionTag.java Thu Jun 18 03:13:34 2009
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.ki.web.tags;
+package org.apache.shiro.web.tags;
/**
* @author Les Hazlewood
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/LacksRoleTag.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/LacksRoleTag.java?rev=785881&r1=785781&r2=785881&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/LacksRoleTag.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/LacksRoleTag.java Thu Jun 18 03:13:34 2009
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.ki.web.tags;
+package org.apache.shiro.web.tags;
/**
* @author Les Hazlewood
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/NotAuthenticatedTag.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/NotAuthenticatedTag.java?rev=785881&r1=785781&r2=785881&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/NotAuthenticatedTag.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/NotAuthenticatedTag.java Thu Jun 18 03:13:34 2009
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.ki.web.tags;
+package org.apache.shiro.web.tags;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
@@ -29,7 +29,7 @@
* JSP tag that renders the tag body only if the current user has <em>not</em> executed a successful authentication
* attempt <em>during their current session</em>.
*
- * <p>The logically opposite tag of this one is the {@link org.apache.ki.web.tags.AuthenticatedTag}.
+ * <p>The logically opposite tag of this one is the {@link org.apache.shiro.web.tags.AuthenticatedTag}.
*
* @author Jeremy Haile
* @since 0.2
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/PermissionTag.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/PermissionTag.java?rev=785881&r1=785781&r2=785881&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/PermissionTag.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/PermissionTag.java Thu Jun 18 03:13:34 2009
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.ki.web.tags;
+package org.apache.shiro.web.tags;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/PrincipalTag.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/PrincipalTag.java?rev=785881&r1=785781&r2=785881&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/PrincipalTag.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/PrincipalTag.java Thu Jun 18 03:13:34 2009
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.ki.web.tags;
+package org.apache.shiro.web.tags;
import java.beans.BeanInfo;
import java.beans.Introspector;
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/RoleTag.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/RoleTag.java?rev=785881&r1=785781&r2=785881&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/RoleTag.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/tags/RoleTag.java Thu Jun 18 03:13:34 2009
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.ki.web.tags;
+package org.apache.shiro.web.tags;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;