You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shiro.apache.org by lh...@apache.org on 2009/07/22 03:11:54 UTC
svn commit: r796597 - in /incubator/shiro/trunk:
core/src/main/java/org/apache/shiro/mgt/
core/src/main/java/org/apache/shiro/subject/
core/src/test/java/org/apache/shiro/session/mgt/
web/src/main/java/org/apache/shiro/web/ web/src/main/java/org/apache...
Author: lhazlewood
Date: Wed Jul 22 01:11:54 2009
New Revision: 796597
URL: http://svn.apache.org/viewvc?rev=796597&view=rev
Log:
SHIRO-30 - enabled SecurityManager#getSubject(Map initData) method and altered underlying implementations to support this construct. This allowed for a significant amount of duplicate boilerplate code to be consolidated into the DefaultSubjectFactory implementation
Modified:
incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/DefaultSecurityManager.java
incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/DefaultSubjectFactory.java
incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/SecurityManager.java
incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/SubjectFactory.java
incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/DelegatingSubject.java
incubator/shiro/trunk/core/src/test/java/org/apache/shiro/session/mgt/DefaultSessionManagerTest.java
incubator/shiro/trunk/core/src/test/java/org/apache/shiro/session/mgt/DelegatingSessionTest.java
incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebSubjectFactory.java
incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java
incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DelegatingWebSessionManager.java
incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/DelegatingWebSecurityManagerTest.java
Modified: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/DefaultSecurityManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/DefaultSecurityManager.java?rev=796597&r1=796596&r2=796597&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/DefaultSecurityManager.java (original)
+++ incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/DefaultSecurityManager.java Wed Jul 22 01:11:54 2009
@@ -18,18 +18,7 @@
*/
package org.apache.shiro.mgt;
-import java.io.Serializable;
-import java.net.InetAddress;
-import java.util.Collection;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.shiro.authc.AuthenticationException;
-import org.apache.shiro.authc.AuthenticationInfo;
-import org.apache.shiro.authc.AuthenticationToken;
-import org.apache.shiro.authc.Authenticator;
-import org.apache.shiro.authc.LogoutAware;
+import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.Authorizer;
import org.apache.shiro.crypto.Cipher;
@@ -40,6 +29,13 @@
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ThreadContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
/**
@@ -48,7 +44,7 @@
* authentication, authorization, and session operations to wrapped {@link Authenticator}, {@link Authorizer}, and
* {@link org.apache.shiro.session.mgt.SessionManager SessionManager} instances respectively via superclass
* implementation.</p>
- *
+ * <p/>
* <p>To greatly reduce and simplify configuration, this implementation (and its superclasses) will
* create suitable defaults for all of its required dependencies, <em>except</em> the required one or more
* {@link Realm Realm}s. Because <code>Realm</code> implementations usually interact with an application's data model,
@@ -56,23 +52,22 @@
* <tt>Realm</tt> implementation that 'knows' about your application's data/security model
* (via {@link #setRealm} or one of the overloaded constructors). All other attributes in this class hierarchy
* will have suitable defaults for most enterprise applications.</p>
- *
+ * <p/>
* <p><b>RememberMe notice</b>: This class supports the ability to configure a
* {@link #setRememberMeManager RememberMeManager}
* for <tt>RememberMe</tt> identity services for login/logout, BUT, a default instance <em>will not</em> be created
* for this attribute at startup.
- *
+ * <p/>
* <p>Because RememberMe services are inherently client tier-specific and
* therefore aplication-dependent, if you want <tt>RememberMe</tt> services enabled, you will have to specify an
* instance yourself via the {@link #setRememberMeManager(RememberMeManager) setRememberMeManager}
* mutator. However if you're reading this JavaDoc with the
* expectation of operating in a Web environment, take a look at the
- * {@link org.apache.shiro.web.DefaultWebSecurityManager DefaultWebSecurityManager} implementation, which
+ * {@code org.apache.shiro.web.DefaultWebSecurityManager} implementation, which
* <em>does</em> support <tt>RememberMe</tt> services by default at startup.
*
* @author Les Hazlewood
* @author Jeremy Haile
- * @see org.apache.shiro.web.DefaultWebSecurityManager
* @since 0.2
*/
public class DefaultSecurityManager extends SessionsSecurityManager {
@@ -197,13 +192,22 @@
return ThreadContext.getSessionId();
}
- protected Subject createSubject() {
- Subject subject = null;
+ protected Session getSession(Serializable id) {
+ if (!isValid(id)) {
+ String msg = "Specified id [" + id + "] does not correspond to a valid Session It either " +
+ "does not exist or the corresponding session has been stopped or expired.";
+ throw new InvalidSessionException(msg, id);
+ }
+ return new DelegatingSession(this, id);
+ }
+
+ protected Subject createSubject() {
Serializable sessionId = getCurrentSessionId();
+ Session session = null;
if (sessionId != null) {
try {
- subject = getSubjectBySessionId(sessionId);
+ session = getSession(sessionId);
} catch (InvalidSessionException e) {
if (log.isDebugEnabled()) {
log.debug("Session id referenced on the current thread [" + sessionId + "] is invalid. " +
@@ -218,12 +222,22 @@
}
}
- if (subject == null) {
- PrincipalCollection principals = getRememberedIdentity();
- return getSubjectFactory().createSubject(principals, null, false, null);
+ PrincipalCollection principals = getRememberedIdentity();
+ return createSubject(principals, session);
+ }
+
+ protected Subject createSubject(PrincipalCollection principals, Session session) {
+ Map<String, Object> context = new HashMap<String, Object>(2);
+
+ if (principals != null && !principals.isEmpty()) {
+ context.put(SubjectFactory.PRINCIPALS, principals);
+ }
+ if (session != null) {
+ context.put(SubjectFactory.SESSION, session);
}
- return subject;
+ SubjectFactory sf = getSubjectFactory();
+ return sf.createSubject(context);
}
/**
@@ -235,12 +249,20 @@
* authenticated user.
*/
protected Subject createSubject(AuthenticationToken token, AuthenticationInfo info) {
- return getSubjectFactory().createSubject(token, info, getSubject(false));
+ Map<String, Object> context = new HashMap<String, Object>();
+ context.put(SubjectFactory.AUTHENTICATED, Boolean.TRUE);
+ context.put(SubjectFactory.AUTHENTICATION_TOKEN, token);
+ context.put(SubjectFactory.AUTHENTICATION_INFO, info);
+ Subject subject = getSubject(false);
+ if (subject != null) {
+ context.put(SubjectFactory.SUBJECT, subject);
+ }
+ return getSubjectFactory().createSubject(context);
}
/**
* Binds a <tt>Subject</tt> instance created after authentication to the application for later use.
- *
+ * <p/>
* <p>The default implementation merely binds the argument to the thread local via the {@link ThreadContext}.
* Should be overridden by subclasses for environment-specific binding (e.g. web environment, etc).
*
@@ -317,7 +339,7 @@
/**
* First authenticates the <tt>AuthenticationToken</tt> argument, and if successful, constructs a
* <tt>Subject</tt> instance representing the authenticated account's identity.
- *
+ * <p/>
* <p>Once constructed, the <tt>Subject</tt> instance is then {@link #bind bound} to the application for
* subsequent access before being returned to the caller.
*
@@ -359,6 +381,13 @@
rememberMeLogout(subjectIdentifier);
}
+ /**
+ * @since 1.0
+ */
+ public Subject getSubject(Map context) {
+ return getSubjectFactory().createSubject(context);
+ }
+
protected Subject getSubject(PrincipalCollection principals) {
//Method arg is ignored at the moment - retrieve from the environment if it exists:
return getSubject(false);
@@ -449,29 +478,17 @@
return getSubject(true);
}
- protected PrincipalCollection getPrincipals(Session session) {
- return (PrincipalCollection) session.getAttribute(SessionSubjectBinder.PRINCIPALS_SESSION_KEY);
- }
-
- protected boolean isAuthenticated(Session session, PrincipalCollection principals) {
- if (principals != null) {
- Boolean authc = (Boolean) session.getAttribute(SessionSubjectBinder.AUTHENTICATED_SESSION_KEY);
- return authc != null && authc;
- }
- return false;
- }
-
/**
* Acquires the {@link Subject Subject} that owns the {@link Session Session} with the specified {@code sessionId}.
- *
- * <p><b>Although simple in concept, this method provides incredibly powerful functionality:</b>
- *
- * <p>The ability to reference a {@code Subject} and their server-side session
+ * <p/>
+ * <b>Although simple in concept, this method provides incredibly powerful functionality:</b>
+ * <p/>
+ * The ability to reference a {@code Subject} and their server-side session
* <em>across clients of different mediums</em> such as web applications, Java applets,
* standalone C# clients over XMLRPC and/or SOAP, and many others. This is a <em>huge</em>
* benefit in heterogeneous enterprise applications.
- *
- * <p>To maintain session integrity across client mediums, the {@code sessionId} <b>must</b> be transmitted
+ * <p/>
+ * To maintain session integrity across client mediums, the {@code sessionId} <b>must</b> be transmitted
* to all client mediums securely (e.g. over SSL) to prevent man-in-the-middle attacks. This
* is nothing new - all web applications are susceptible to the same problem when transmitting
* {@code Cookie}s or when using URL rewriting. As long as the
@@ -493,17 +510,12 @@
* @since 1.0
*/
private Subject getSubjectBySessionId(Serializable sessionId) throws InvalidSessionException, AuthorizationException {
- if (!isValid(sessionId)) {
- String msg = "Specified id [" + sessionId + "] does not correspond to a valid Session It either " +
- "does not exist or the corresponding session has been stopped or expired.";
- throw new InvalidSessionException(msg, sessionId);
- }
+ Session session = getSession(sessionId);
- Session existing = new DelegatingSession(this, sessionId);
- PrincipalCollection principals = getPrincipals(existing);
- boolean authenticated = isAuthenticated(existing, principals);
- InetAddress host = existing.getHostAddress();
+ Map<String, Object> context = new HashMap<String, Object>(1);
+ context.put(SubjectFactory.SESSION, session);
- return getSubjectFactory().createSubject(principals, existing, authenticated, host);
+ SubjectFactory sf = getSubjectFactory();
+ return sf.createSubject(context);
}
}
Modified: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/DefaultSubjectFactory.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/DefaultSubjectFactory.java?rev=796597&r1=796596&r2=796597&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/DefaultSubjectFactory.java (original)
+++ incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/DefaultSubjectFactory.java Wed Jul 22 01:11:54 2009
@@ -18,8 +18,6 @@
*/
package org.apache.shiro.mgt;
-import java.net.InetAddress;
-
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.InetAuthenticationToken;
@@ -29,6 +27,9 @@
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ThreadContext;
+import java.net.InetAddress;
+import java.util.Map;
+
/**
* Default {@link SubjectFactory SubjectFactory} implementation that creates {@link DelegatingSubject DelegatingSubject}
@@ -56,6 +57,22 @@
this.securityManager = securityManager;
}
+ @SuppressWarnings({"unchecked"})
+ protected static <E> E getTypedValue(Map context, String key, Class<E> type) {
+ E found = null;
+ Object o = context.get(key);
+ if (o != null) {
+ if (!type.isAssignableFrom(o.getClass())) {
+ String msg = "Invalid object found in context Map under key [" + key + "]. Expected type " +
+ "was [" + type.getName() + "], but the object under that key is of type " +
+ "[" + o.getClass().getName() + "].";
+ throw new IllegalArgumentException(msg);
+ }
+ found = (E) o;
+ }
+ return found;
+ }
+
private void assertPrincipals(AuthenticationInfo info) {
PrincipalCollection principals = info.getPrincipals();
if (principals == null || principals.isEmpty()) {
@@ -64,29 +81,104 @@
}
}
- public Subject createSubject(AuthenticationToken token, AuthenticationInfo info, Subject existing) {
- assertPrincipals(info);
+ protected boolean isAuthenticationContext(Map context) {
+ return context.containsKey(SubjectFactory.AUTHENTICATION_TOKEN);
+ }
+
+ protected static boolean isEmpty(PrincipalCollection principals) {
+ return principals == null || principals.isEmpty();
+ }
+
+ protected PrincipalCollection getPrincipals(Map context, Session session) {
+ PrincipalCollection principals = getTypedValue(context, SubjectFactory.PRINCIPALS, PrincipalCollection.class);
+
+ if (isEmpty(principals)) {
+ //check to see if they were just authenticated:
+ AuthenticationInfo info = getTypedValue(context, SubjectFactory.AUTHENTICATION_INFO, AuthenticationInfo.class);
+ if (info != null) {
+ principals = info.getPrincipals();
+ }
+ }
+
+ if (isEmpty(principals)) {
+ Subject subject = getTypedValue(context, SubjectFactory.SUBJECT, Subject.class);
+ if (subject != null) {
+ principals = subject.getPrincipals();
+ }
+ }
+
+ if (isEmpty(principals)) {
+ //try the session:
+ if (session != null) {
+ principals = (PrincipalCollection) session.getAttribute(SessionSubjectBinder.PRINCIPALS_SESSION_KEY);
+ }
+ }
+
+ return principals;
+ }
+
+ protected Session getSession(Map context) {
+ Session session = getTypedValue(context, SubjectFactory.SESSION, Session.class);
- //get any existing session that may exist - we don't want to lose it:
- Session session = null;
- if (existing != null) {
- session = existing.getSession(false);
+ if (session == null) {
+ //try the Subject if it exists:
+ Subject existingSubject = getTypedValue(context, SubjectFactory.SUBJECT, Subject.class);
+ if (existingSubject != null) {
+ session = existingSubject.getSession(false);
+ }
}
- InetAddress authcSourceIP = null;
- if (token instanceof InetAuthenticationToken) {
- authcSourceIP = ((InetAuthenticationToken) token).getInetAddress();
+ return session;
+ }
+
+ protected InetAddress getInetAddress(Map context, Session session) {
+ InetAddress inet = getTypedValue(context, SubjectFactory.INET_ADDRESS, InetAddress.class);
+
+ if (inet == null) {
+ //check to see if there is an AuthenticationToken from which to retrieve it:
+ AuthenticationToken token = getTypedValue(context, SubjectFactory.AUTHENTICATION_TOKEN, AuthenticationToken.class);
+ if (token instanceof InetAuthenticationToken) {
+ inet = ((InetAuthenticationToken) token).getInetAddress();
+ }
}
- if (authcSourceIP == null) {
- //try the thread local:
- authcSourceIP = ThreadContext.getInetAddress();
+
+ if (inet == null) {
+ if (session != null) {
+ inet = session.getHostAddress();
+ }
+ }
+
+ if (inet == null) {
+ //fall back to the thread local if it exists:
+ inet = ThreadContext.getInetAddress();
}
- return createSubject(info.getPrincipals(), session, true, authcSourceIP);
+ return inet;
+ }
+
+ protected boolean isAuthenticated(Map context, Session session) {
+ Boolean authc = getTypedValue(context, SubjectFactory.AUTHENTICATED, Boolean.class);
+ if (authc == null) {
+ //see if there is an AuthenticationInfo object. If so, the very presence of one indicates a successful
+ //authentication attempt:
+ AuthenticationInfo info = getTypedValue(context, SubjectFactory.AUTHENTICATION_INFO, AuthenticationInfo.class);
+ authc = info != null;
+ }
+ if (!authc) {
+ //fall back to a session check:
+ if (session != null) {
+ Boolean sessionAuthc = (Boolean) session.getAttribute(SessionSubjectBinder.AUTHENTICATED_SESSION_KEY);
+ authc = sessionAuthc != null && sessionAuthc;
+ }
+ }
+ return authc;
}
- public Subject createSubject(PrincipalCollection principals, Session existing,
- boolean authenticated, InetAddress inetAddress) {
- return new DelegatingSubject(principals, authenticated, inetAddress, existing, getSecurityManager());
+ public Subject createSubject(Map context) {
+ Session session = getSession(context);
+ PrincipalCollection principals = getPrincipals(context, session);
+ boolean authenticated = isAuthenticated(context, session);
+ InetAddress inet = getInetAddress(context, session);
+ return new DelegatingSubject(principals, authenticated, inet, session, getSecurityManager());
}
}
Modified: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/SecurityManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/SecurityManager.java?rev=796597&r1=796596&r2=796597&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/SecurityManager.java (original)
+++ incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/SecurityManager.java Wed Jul 22 01:11:54 2009
@@ -26,6 +26,8 @@
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
+import java.util.Map;
+
/**
* A <tt>SecurityManager</tt> executes all security operations for <em>all</em> Subjects (aka users) across a
@@ -105,6 +107,27 @@
*/
Subject getSubject();
+ /**
+ * Returns the {@code Subject} instance reflecting the specified contextual data.
+ * <p/>
+ * The context can be anything needed by this {@code SecurityManager} to construct a {@code Subject} instance.
+ * Most Shiro end-users will never call this method - it exists primarily for
+ * framework development and to support any underlying {@link SubjectFactory SubjectFactory} implementations used
+ * by the {@code SecurityManager}.
+ * <h4>Usage</h4>
+ * The difference between calling this method and {@link #getSubject() getSubject()} is that the {@code Subject}
+ * instance returned from this method is not automatically 'bound' to the application
+ * for further use. That is, after calling this method, a call to {@code getSubject()} will not necessarily return
+ * the same instance. Callers are expected to know that {@code Subject} instances have local scope only and any
+ * other further use beyond the calling method must be managed manually.
+ *
+ * @param context any data needed to direct how the Subject should be constructed.
+ * @return the {@code Subject} instance reflecting the specified initialization data.
+ * @see SubjectFactory#createSubject(java.util.Map)
+ * @since 1.0
+ */
+ Subject getSubject(Map context);
+
/*Subject getSubject(Map initData);
Subject getSubjectBySessionId(Serializable sessionId);
Modified: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/SubjectFactory.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/SubjectFactory.java?rev=796597&r1=796596&r2=796597&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/SubjectFactory.java (original)
+++ incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/SubjectFactory.java Wed Jul 22 01:11:54 2009
@@ -18,13 +18,9 @@
*/
package org.apache.shiro.mgt;
-import org.apache.shiro.authc.AuthenticationInfo;
-import org.apache.shiro.authc.AuthenticationToken;
-import org.apache.shiro.session.Session;
-import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
-import java.net.InetAddress;
+import java.util.Map;
/**
* A {@code SubjectFactory} is responsible for returning {@link Subject Subject} instances as needed.
@@ -34,37 +30,29 @@
*/
public interface SubjectFactory {
- /**
- * Returns a {@code Subject} instance reflecting the state of a <em>successful</em> authentication attempt.
- * <p/>
- * The '{@code existing}' {@code Subject} method argument is the {@code Subject} that executed the
- * authentication attempt but still reflects an unauthenticated state. The instance returned from this method
- * is the {@code Subject} instance to use for future application use and reflects an authenticated state.
- *
- * @param token the {@code AuthenticationToken} submitted during the successful authentication attempt.
- * @param info the {@code AuthenticationInfo} generated due to the successful authentication attempt.
- * @param existing the {@code Subject} that executed the attempt, still in an 'unauthenticated' state.
- * @return the {@code Subject} for the application to use going forward, but in an 'authenticated' state.
- */
- Subject createSubject(AuthenticationToken token, AuthenticationInfo info, Subject existing);
+ public static final String AUTHENTICATION_TOKEN = SubjectFactory.class.getName() + ".AUTHENTICATION_TOKEN";
+
+ public static final String AUTHENTICATION_INFO = SubjectFactory.class.getName() + ".AUTHENTICATION_INFO";
+
+ public static final String SUBJECT = SubjectFactory.class.getName() + ".SUBJECT";
+
+ public static final String PRINCIPALS = SubjectFactory.class.getName() + ".PRINCIPALS";
+
+ public static final String SESSION = SubjectFactory.class.getName() + ".SESSION";
+
+ public static final String AUTHENTICATED = SubjectFactory.class.getName() + ".AUTHENTICATED";
+
+ public static final String INET_ADDRESS = SubjectFactory.class.getName() + ".INET_ADDRESS";
/**
- * Returns a {@code Subject} instance reflecting the specified Subject identity (aka 'principals'), any
- * existing {@code Session} that might be in place for that identity, whether or not the Subject is to be
- * considered already authenticated, and the originating host from where the Subject instance to be created is
- * being acquired.
+ * Creates a new Subject instance reflecting the state of the specified contextual data. The data would be
+ * anything required to required to construct a {@code Subject} instance and its contents can vary based on
+ * environment.
*
- * @param principals the identifying attributes of the Subject instance to be created, or
- * {@code null} if the Subject's identity is unknown because they haven't logged in yet and are not 'remembered'
- * from {@code RememberMe} services.
- * @param existing any {@link org.apache.shiro.session.Session Session} that might be in place for the specified {@link org.apache.shiro.subject.Subject}, or
- * {@code null} if there is no session yet created for the specified {@code Subject}. If non-{@code null},
- * it should be retained and used by the {@code Subject} instance returned from this method call.
- * @param authenticated whether or not the {@code Subject} instance returned should be considered already
- * authenticated.
- * @param originatingHost the host location indicating where the {@code Subject} is located.
- * @return a {@code Subject} instance representing the aggregate state of the specified method arguments.
+ * @param context the contextual data to be used by the implementation to construct an appropriate {@code Subject}
+ * instance.
+ * @return a {@code Subject} instance created based on the specified context.
*/
- Subject createSubject(PrincipalCollection principals, Session existing, boolean authenticated, InetAddress originatingHost);
+ Subject createSubject(Map context);
}
Modified: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/DelegatingSubject.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/DelegatingSubject.java?rev=796597&r1=796596&r2=796597&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/DelegatingSubject.java (original)
+++ incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/DelegatingSubject.java Wed Jul 22 01:11:54 2009
@@ -35,7 +35,6 @@
import java.io.Serializable;
import java.net.InetAddress;
-import java.net.UnknownHostException;
import java.util.Collection;
import java.util.List;
@@ -79,7 +78,7 @@
protected SecurityManager securityManager;
public DelegatingSubject(SecurityManager securityManager) {
- this(null, false, getLocalHost(), null, securityManager);
+ this(null, false, null, null, securityManager);
}
public DelegatingSubject(PrincipalCollection principals, boolean authenticated, InetAddress inetAddress,
@@ -89,27 +88,16 @@
}
this.securityManager = securityManager;
this.principals = principals;
-
this.authenticated = authenticated;
if (inetAddress != null) {
this.inetAddress = inetAddress;
- } else {
- this.inetAddress = getLocalHost();
}
if (session != null) {
this.session = decorate(session);
}
}
- protected static InetAddress getLocalHost() {
- try {
- return InetAddress.getLocalHost();
- } catch (UnknownHostException e) {
- return null;
- }
- }
-
protected Session decorate(Session session) {
if (session == null) {
throw new IllegalArgumentException("session cannot be null");
Modified: incubator/shiro/trunk/core/src/test/java/org/apache/shiro/session/mgt/DefaultSessionManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/test/java/org/apache/shiro/session/mgt/DefaultSessionManagerTest.java?rev=796597&r1=796596&r2=796597&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/test/java/org/apache/shiro/session/mgt/DefaultSessionManagerTest.java (original)
+++ incubator/shiro/trunk/core/src/test/java/org/apache/shiro/session/mgt/DefaultSessionManagerTest.java Wed Jul 22 01:11:54 2009
@@ -1,3 +1,21 @@
+/*
+ * 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.session.mgt;
import org.apache.shiro.util.ThreadContext;
@@ -42,7 +60,7 @@
sm.setGlobalSessionTimeout(100);
Serializable sessionId = sm.start((InetAddress) null);
assertTrue(sm.isValid(sessionId));
- sleep(100);
+ sleep(150);
assertFalse(sm.isValid(sessionId));
}
}
Modified: incubator/shiro/trunk/core/src/test/java/org/apache/shiro/session/mgt/DelegatingSessionTest.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/test/java/org/apache/shiro/session/mgt/DelegatingSessionTest.java?rev=796597&r1=796596&r2=796597&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/test/java/org/apache/shiro/session/mgt/DelegatingSessionTest.java (original)
+++ incubator/shiro/trunk/core/src/test/java/org/apache/shiro/session/mgt/DelegatingSessionTest.java Wed Jul 22 01:11:54 2009
@@ -1,10 +1,29 @@
+/*
+ * 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.session.mgt;
-import org.junit.Before;
+import org.apache.shiro.util.ThreadContext;
import org.junit.After;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import org.junit.Before;
import org.junit.Test;
-import static org.junit.Assert.*;
-import org.apache.shiro.util.ThreadContext;
import java.io.Serializable;
import java.net.InetAddress;
@@ -21,7 +40,7 @@
public void setup() {
ThreadContext.clear();
sm = new DefaultSessionManager();
- Serializable sessionId = sm.start((InetAddress)null);
+ Serializable sessionId = sm.start((InetAddress) null);
this.session = new DelegatingSession(sm, sessionId);
}
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebSubjectFactory.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebSubjectFactory.java?rev=796597&r1=796596&r2=796597&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebSubjectFactory.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebSubjectFactory.java Wed Jul 22 01:11:54 2009
@@ -18,18 +18,16 @@
*/
package org.apache.shiro.web;
-import java.net.InetAddress;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-
import org.apache.shiro.mgt.DefaultSubjectFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.mgt.SessionSubjectBinder;
import org.apache.shiro.session.Session;
-import org.apache.shiro.subject.PrincipalCollection;
-import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.session.WebSessionManager;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import java.util.Map;
+
/**
* @author Les Hazlewood
@@ -62,33 +60,10 @@
this.webSessionManager = webSessionManager;
}
- protected PrincipalCollection getPrincipals(Session existing) {
- PrincipalCollection principals = null;
- if (existing != null) {
- principals = (PrincipalCollection) existing.getAttribute(PRINCIPALS_SESSION_KEY);
- }
-// if (principals == null) {
-// //check remember me:
-// principals = getRememberedIdentity();
-// if (principals != null && existing != null) {
-// existing.setAttribute(PRINCIPALS_SESSION_KEY, principals);
-// }
-// }
- return principals;
- }
-
- protected boolean isAuthenticated(Session session) {
- Boolean value = null;
- if (session != null) {
- value = (Boolean) session.getAttribute(AUTHENTICATED_SESSION_KEY);
- }
- return value != null && value;
- }
-
protected Session getWebSession() {
ServletRequest request = WebUtils.getServletRequest();
ServletResponse response = WebUtils.getServletResponse();
- if ( request == null || response == null ) {
+ if (request == null || response == null) {
//no current web request - probably a remote method invocation that didn't come in via a servlet request:
return null;
} else {
@@ -97,31 +72,11 @@
}
@Override
- public Subject createSubject(PrincipalCollection principals, Session existing, boolean authenticated, InetAddress inetAddress) {
- Session session = existing;
+ protected Session getSession(Map context) {
+ Session session = super.getSession(context);
if (session == null) {
session = getWebSession();
}
-
- PrincipalCollection pc = principals;
- if (pc == null) {
- pc = getPrincipals(session);
- }
-
- boolean authc = authenticated;
- if (!authc) {
- //check session to be sure:
- authc = isAuthenticated(session);
- }
-
- InetAddress inet = inetAddress;
- if (inet == null) {
- ServletRequest request = WebUtils.getServletRequest();
- if ( request != null ) {
- inet = WebUtils.getInetAddress(request);
- }
- }
-
- return super.createSubject(pc, session, authc, inet);
+ return session;
}
}
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=796597&r1=796596&r2=796597&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 Wed Jul 22 01:11:54 2009
@@ -329,9 +329,17 @@
protected void onStop(Session session) {
super.onStop(session);
+ removeSessionIdCookie();
+ }
+
+ protected void onExpiration(Session session) {
+ super.onExpiration(session);
+ removeSessionIdCookie();
+ }
+
+ protected void removeSessionIdCookie() {
ServletRequest request = WebUtils.getRequiredServletRequest();
ServletResponse response = WebUtils.getRequiredServletResponse();
removeSessionIdCookie(request, response);
- getSessionIdCookieAttribute().removeValue(request, response);
}
}
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DelegatingWebSessionManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DelegatingWebSessionManager.java?rev=796597&r1=796596&r2=796597&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DelegatingWebSessionManager.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DelegatingWebSessionManager.java Wed Jul 22 01:11:54 2009
@@ -21,11 +21,9 @@
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.DelegatingSession;
-import org.apache.shiro.session.mgt.SessionFactory;
import org.apache.shiro.session.mgt.SessionManager;
import java.io.Serializable;
-import java.net.InetAddress;
import java.util.Map;
/**
@@ -46,6 +44,9 @@
*/
public class DelegatingWebSessionManager extends DefaultWebSessionManager {
+ private static final String THREAD_CONTEXT_SESSION_KEY =
+ DelegatingWebSessionManager.class.getName() + ".THREAD_CONTEXT_SESSION_KEY";
+
private SessionManager delegateSessionManager = null;
public DelegatingWebSessionManager() {
@@ -84,11 +85,7 @@
@Override
protected Session doCreateSession(Map initData) {
assertDelegateExists();
- InetAddress host = null;
- if (initData != null && initData.containsKey(SessionFactory.ORIGINATING_HOST_KEY)) {
- host = (InetAddress) initData.get(SessionFactory.ORIGINATING_HOST_KEY);
- }
- Serializable sessionId = this.delegateSessionManager.start(host);
+ Serializable sessionId = this.delegateSessionManager.start(initData);
return new DelegatingSession(this, sessionId);
}
@@ -100,15 +97,36 @@
@Override
protected Session retrieveSessionFromDataSource(Serializable id) throws InvalidSessionException {
+ /*Session session = (Session)ThreadContext.get(THREAD_CONTEXT_SESSION_KEY);
+ if ( session != null ) {
+ return session;
+ }*/
assertDelegateExists();
this.delegateSessionManager.checkValid(id);
- //we need the DelegatingSession to reference the delegateSessionManager and not 'this' so
- //we avoid an infinite loop:
return new DelegatingSession(this.delegateSessionManager, id);
+ /*//we need the DelegatingSession to reference the delegateSessionManager and not 'this' so
+ //we avoid an infinite loop:
+ session = new DelegatingSession(this.delegateSessionManager, id);
+ ThreadContext.put(THREAD_CONTEXT_SESSION_KEY, session);
+
+ return session;*/
+ }
+
+ @Override
+ protected void onChange(Session session) {
+ //do nothing - back-end will react to change as appropriate
}
@Override
protected void doValidate(Session session) throws InvalidSessionException {
- session.touch();
+ /*if ( session == null ) {
+ throw new InvalidSessionException("Session method argument is null!" );
+ }
+ Serializable id = session.getId();
+ if ( id == null ) {
+ throw new InvalidSessionException("Session does not have an id!" );
+ }
+ assertDelegateExists();
+ this.delegateSessionManager.checkValid(id);*/
}
}
Modified: incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/DelegatingWebSecurityManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/DelegatingWebSecurityManagerTest.java?rev=796597&r1=796596&r2=796597&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/DelegatingWebSecurityManagerTest.java (original)
+++ incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/DelegatingWebSecurityManagerTest.java Wed Jul 22 01:11:54 2009
@@ -1,31 +1,26 @@
package org.apache.shiro.web;
-import org.junit.Before;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.mgt.DefaultSecurityManager;
+import org.apache.shiro.realm.text.PropertiesRealm;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.subject.Subject;
+import org.apache.shiro.util.ThreadContext;
+import static org.easymock.EasyMock.*;
import org.junit.After;
-import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import org.apache.shiro.util.ThreadContext;
-import org.apache.shiro.subject.Subject;
-import org.apache.shiro.session.Session;
-import org.apache.shiro.session.mgt.DefaultSessionManager;
-import org.apache.shiro.realm.text.PropertiesRealm;
-import org.apache.shiro.SecurityUtils;
-import org.apache.shiro.mgt.DefaultSecurityManager;
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
+import org.junit.Before;
+import org.junit.Test;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
/**
- * Created by IntelliJ IDEA.
- * User: lhazlewood
- * Date: Jul 18, 2009
- * Time: 7:46:22 PM
- * To change this template use File | Settings | File Templates.
+ * Unit test for the {@link org.apache.shiro.web.DelegatingWebSecurityManager} implementation.
+ *
+ * @since 1.0
*/
public class DelegatingWebSecurityManagerTest {
@@ -36,7 +31,6 @@
public void setup() {
delegate = new DefaultSecurityManager();
delegate.setRealm(new PropertiesRealm());
- delegate.setGlobalSessionTimeout(-1);
sm = new DelegatingWebSecurityManager();
sm.setDelegateSecurityManager(delegate);
SecurityUtils.setSecurityManager(sm);
@@ -60,7 +54,8 @@
@Test
public void testSessionTimeout() {
- long globalTimeout = -1;
+ long globalTimeout = 100;
+ delegate.setGlobalSessionTimeout(globalTimeout);
HttpServletRequest mockRequest = createNiceMock(HttpServletRequest.class);
WebUtils.bind(mockRequest);
@@ -75,15 +70,13 @@
Subject subject = sm.getSubject();
Session session = subject.getSession();
Serializable origId = session.getId();
- assertEquals(session.getTimeout(), globalTimeout);
- session.setTimeout(100);
- assertEquals(session.getTimeout(), 100);
- sleep(150);
+ assertEquals(globalTimeout, session.getTimeout());
+ session.setTimeout(125);
+ assertEquals(125, session.getTimeout());
+ sleep(175);
//now the underlying session should have been expired and a new one replaced by default.
//so ensure the replaced session has the default session timeout:
- assertEquals(session.getTimeout(), globalTimeout);
+ assertEquals(globalTimeout, session.getTimeout());
assertFalse(origId.equals(session.getId())); //new ID would have been generated
-
- //verify(mockRequest);
}
}