001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing,
013     * software distributed under the License is distributed on an
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     * KIND, either express or implied.  See the License for the
016     * specific language governing permissions and limitations
017     * under the License.
018     */
019    package org.apache.shiro.subject;
020    
021    import org.apache.shiro.SecurityUtils;
022    import org.apache.shiro.authc.AuthenticationException;
023    import org.apache.shiro.authc.AuthenticationToken;
024    import org.apache.shiro.authz.AuthorizationException;
025    import org.apache.shiro.authz.Permission;
026    import org.apache.shiro.mgt.SecurityManager;
027    import org.apache.shiro.mgt.SubjectFactory;
028    import org.apache.shiro.session.Session;
029    import org.apache.shiro.subject.support.DefaultSubjectContext;
030    import org.apache.shiro.util.CollectionUtils;
031    import org.apache.shiro.util.StringUtils;
032    
033    import java.io.Serializable;
034    import java.util.Collection;
035    import java.util.List;
036    import java.util.concurrent.Callable;
037    
038    /**
039     * A {@code Subject} represents state and security operations for a <em>single</em> application user.
040     * These operations include authentication (login/logout), authorization (access control), and
041     * session access. It is Shiro's primary mechanism for single-user security functionality.
042     * <h3>Acquiring a Subject</h3>
043     * To acquire the currently-executing {@code Subject}, application developers will almost always use
044     * {@code SecurityUtils}:
045     * <pre>
046     * {@link SecurityUtils SecurityUtils}.{@link org.apache.shiro.SecurityUtils#getSubject() getSubject()}</pre>
047     * Almost all security operations should be performed with the {@code Subject} returned from this method.
048     * <h3>Permission methods</h3>
049     * Note that there are many *Permission methods in this interface overloaded to accept String arguments instead of
050     * {@link Permission Permission} instances. They are a convenience allowing the caller to use a String representation of
051     * a {@link Permission Permission} if desired.  The underlying Authorization subsystem implementations will usually
052     * simply convert these String values to {@link Permission Permission} instances and then just call the corresponding
053     * type-safe method.  (Shiro's default implementations do String-to-Permission conversion for these methods using
054     * {@link org.apache.shiro.authz.permission.PermissionResolver PermissionResolver}s.)
055     * <p/>
056     * These overloaded *Permission methods forgo type-saftey for the benefit of convenience and simplicity,
057     * so you should choose which ones to use based on your preferences and needs.
058     *
059     * @author Les Hazlewood
060     * @author Jeremy Haile
061     * @since 0.1
062     */
063    public interface Subject {
064    
065        /**
066         * Returns this Subject's application-wide uniquely identifying principal, or {@code null} if this
067         * Subject is anonymous because it doesn't yet have any associated account data (for example,
068         * if they haven't logged in).
069         * <p/>
070         * The term <em>principal</em> is just a fancy security term for any identifying attribute(s) of an application
071         * user, such as a username, or user id, or public key, or anything else you might use in your application to
072         * identify a user.
073         * <h4>Uniqueness</h4>
074         * Although given names and family names (first/last) are technically considered principals as well,
075         * Shiro expects the object returned from this method to be an identifying attribute unique across
076         * your entire application.
077         * <p/>
078         * This implies that things like given names and family names are usually poor
079         * candidates as return values since they are rarely guaranteed to be unique;  Things often used for this value:
080         * <ul>
081         * <li>A {@code long} RDBMS surrogate primary key</li>
082         * <li>An application-unique username</li>
083         * <li>A {@link java.util.UUID UUID}</li>
084         * <li>An LDAP Unique ID</li>
085         * </ul>
086         * or any other similar suitable unique mechanism valuable to your application.
087         * <p/>
088         * Most implementations will simply return
089         * <code>{@link #getPrincipals()}.{@link org.apache.shiro.subject.PrincipalCollection#getPrimaryPrincipal() getPrimaryPrincipal()}</code>
090         *
091         * @return this Subject's application-specific unique identity.
092         * @see org.apache.shiro.subject.PrincipalCollection#getPrimaryPrincipal()
093         */
094        Object getPrincipal();
095    
096        /**
097         * Returns this Subject's principals (identifying attributes) in the form of a {@code PrincipalCollection} or
098         * {@code null} if this Subject is anonymous because it doesn't yet have any associated account data (for example,
099         * if they haven't logged in).
100         * <p/>
101         * The word &quot;principals&quot; is nothing more than a fancy security term for identifying attributes associated
102         * with a Subject, aka, application user.  For example, user id, a surname (family/last name), given (first) name,
103         * social security number, nickname, username, etc, are all examples of a principal.
104         *
105         * @return all of this Subject's principals (identifying attributes).
106         * @see #getPrincipal()
107         * @see org.apache.shiro.subject.PrincipalCollection#getPrimaryPrincipal()
108         */
109        PrincipalCollection getPrincipals();
110    
111        /**
112         * Returns {@code true} if this Subject is permitted to perform an action or access a resource summarized by the
113         * specified permission string.
114         * <p/>
115         * This is an overloaded method for the corresponding type-safe {@link Permission Permission} variant.
116         * Please see the class-level JavaDoc for more information on these String-based permission methods.
117         *
118         * @param permission the String representation of a Permission that is being checked.
119         * @return true if this Subject is permitted, false otherwise.
120         * @see #isPermitted(Permission permission)
121         * @since 0.9
122         */
123        boolean isPermitted(String permission);
124    
125        /**
126         * Returns {@code true} if this Subject is permitted to perform an action or access a resource summarized by the
127         * specified permission.
128         * <p/>
129         * More specifically, this method determines if any {@code Permission}s associated
130         * with the subject {@link Permission#implies(Permission) imply} the specified permission.
131         *
132         * @param permission the permission that is being checked.
133         * @return true if this Subject is permitted, false otherwise.
134         */
135        boolean isPermitted(Permission permission);
136    
137        /**
138         * Checks if this Subject implies the given permission strings and returns a boolean array indicating which
139         * permissions are implied.
140         * <p/>
141         * This is an overloaded method for the corresponding type-safe {@link Permission Permission} variant.
142         * Please see the class-level JavaDoc for more information on these String-based permission methods.
143         *
144         * @param permissions the String representations of the Permissions that are being checked.
145         * @return a boolean array where indices correspond to the index of the
146         *         permissions in the given list.  A true value at an index indicates this Subject is permitted for
147         *         for the associated {@code Permission} string in the list.  A false value at an index
148         *         indicates otherwise.
149         * @since 0.9
150         */
151        boolean[] isPermitted(String... permissions);
152    
153        /**
154         * Checks if this Subject implies the given Permissions and returns a boolean array indicating which permissions
155         * are implied.
156         * <p/>
157         * More specifically, this method should determine if each {@code Permission} in
158         * the array is {@link Permission#implies(Permission) implied} by permissions
159         * already associated with the subject.
160         * <p/>
161         * This is primarily a performance-enhancing method to help reduce the number of
162         * {@link #isPermitted} invocations over the wire in client/server systems.
163         *
164         * @param permissions the permissions that are being checked.
165         * @return a boolean array where indices correspond to the index of the
166         *         permissions in the given list.  A true value at an index indicates this Subject is permitted for
167         *         for the associated {@code Permission} object in the list.  A false value at an index
168         *         indicates otherwise.
169         */
170        boolean[] isPermitted(List<Permission> permissions);
171    
172        /**
173         * Returns {@code true} if this Subject implies all of the specified permission strings, {@code false} otherwise.
174         * <p/>
175         * This is an overloaded method for the corresponding type-safe {@link org.apache.shiro.authz.Permission Permission}
176         * variant.  Please see the class-level JavaDoc for more information on these String-based permission methods.
177         *
178         * @param permissions the String representations of the Permissions that are being checked.
179         * @return true if this Subject has all of the specified permissions, false otherwise.
180         * @see #isPermittedAll(Collection)
181         * @since 0.9
182         */
183        boolean isPermittedAll(String... permissions);
184    
185        /**
186         * Returns {@code true} if this Subject implies all of the specified permissions, {@code false} otherwise.
187         * <p/>
188         * More specifically, this method determines if all of the given {@code Permission}s are
189         * {@link Permission#implies(Permission) implied by} permissions already associated with this Subject.
190         *
191         * @param permissions the permissions to check.
192         * @return true if this Subject has all of the specified permissions, false otherwise.
193         */
194        boolean isPermittedAll(Collection<Permission> permissions);
195    
196        /**
197         * Ensures this Subject implies the specified permission String.
198         * <p/>
199         * If this subject's existing associated permissions do not {@link Permission#implies(Permission)} imply}
200         * the given permission, an {@link org.apache.shiro.authz.AuthorizationException} will be thrown.
201         * <p/>
202         * This is an overloaded method for the corresponding type-safe {@link Permission Permission} variant.
203         * Please see the class-level JavaDoc for more information on these String-based permission methods.
204         *
205         * @param permission the String representation of the Permission to check.
206         * @throws org.apache.shiro.authz.AuthorizationException
207         *          if the user does not have the permission.
208         * @since 0.9
209         */
210        void checkPermission(String permission) throws AuthorizationException;
211    
212        /**
213         * Ensures this Subject {@link Permission#implies(Permission) implies} the specified {@code Permission}.
214         * <p/>
215         * If this subject's existing associated permissions do not {@link Permission#implies(Permission) imply}
216         * the given permission, an {@link org.apache.shiro.authz.AuthorizationException} will be thrown.
217         *
218         * @param permission the Permission to check.
219         * @throws org.apache.shiro.authz.AuthorizationException
220         *          if this Subject does not have the permission.
221         */
222        void checkPermission(Permission permission) throws AuthorizationException;
223    
224        /**
225         * Ensures this Subject
226         * {@link org.apache.shiro.authz.Permission#implies(org.apache.shiro.authz.Permission) implies} all of the
227         * specified permission strings.
228         * <p/>
229         * If this subject's existing associated permissions do not
230         * {@link org.apache.shiro.authz.Permission#implies(org.apache.shiro.authz.Permission) imply} all of the given permissions,
231         * an {@link org.apache.shiro.authz.AuthorizationException} will be thrown.
232         * <p/>
233         * This is an overloaded method for the corresponding type-safe {@link Permission Permission} variant.
234         * Please see the class-level JavaDoc for more information on these String-based permission methods.
235         *
236         * @param permissions the string representations of Permissions to check.
237         * @throws AuthorizationException if this Subject does not have all of the given permissions.
238         * @since 0.9
239         */
240        void checkPermissions(String... permissions) throws AuthorizationException;
241    
242        /**
243         * Ensures this Subject
244         * {@link org.apache.shiro.authz.Permission#implies(org.apache.shiro.authz.Permission) implies} all of the
245         * specified permission strings.
246         * <p/>
247         * If this subject's existing associated permissions do not
248         * {@link org.apache.shiro.authz.Permission#implies(org.apache.shiro.authz.Permission) imply} all of the given permissions,
249         * an {@link org.apache.shiro.authz.AuthorizationException} will be thrown.
250         *
251         * @param permissions the Permissions to check.
252         * @throws AuthorizationException if this Subject does not have all of the given permissions.
253         */
254        void checkPermissions(Collection<Permission> permissions) throws AuthorizationException;
255    
256        /**
257         * Returns {@code true} if this Subject has the specified role, {@code false} otherwise.
258         *
259         * @param roleIdentifier the application-specific role identifier (usually a role id or role name).
260         * @return {@code true} if this Subject has the specified role, {@code false} otherwise.
261         */
262        boolean hasRole(String roleIdentifier);
263    
264        /**
265         * Checks if this Subject has the specified roles, returning a boolean array indicating
266         * which roles are associated.
267         * <p/>
268         * This is primarily a performance-enhancing method to help reduce the number of
269         * {@link #hasRole} invocations over the wire in client/server systems.
270         *
271         * @param roleIdentifiers the application-specific role identifiers to check (usually role ids or role names).
272         * @return a boolean array where indices correspond to the index of the
273         *         roles in the given identifiers.  A true value indicates this Subject has the
274         *         role at that index.  False indicates this Subject does not have the role at that index.
275         */
276        boolean[] hasRoles(List<String> roleIdentifiers);
277    
278        /**
279         * Returns {@code true} if this Subject has all of the specified roles, {@code false} otherwise.
280         *
281         * @param roleIdentifiers the application-specific role identifiers to check (usually role ids or role names).
282         * @return true if this Subject has all the roles, false otherwise.
283         */
284        boolean hasAllRoles(Collection<String> roleIdentifiers);
285    
286        /**
287         * Asserts this Subject has the specified role by returning quietly if they do or throwing an
288         * {@link org.apache.shiro.authz.AuthorizationException} if they do not.
289         *
290         * @param roleIdentifier the application-specific role identifier (usually a role id or role name ).
291         * @throws org.apache.shiro.authz.AuthorizationException
292         *          if this Subject does not have the role.
293         */
294        void checkRole(String roleIdentifier) throws AuthorizationException;
295    
296        /**
297         * Asserts this Subject has all of the specified roles by returning quietly if they do or throwing an
298         * {@link org.apache.shiro.authz.AuthorizationException} if they do not.
299         *
300         * @param roleIdentifiers the application-specific role identifiers to check (usually role ids or role names).
301         * @throws org.apache.shiro.authz.AuthorizationException
302         *          if this Subject does not have all of the specified roles.
303         */
304        void checkRoles(Collection<String> roleIdentifiers) throws AuthorizationException;
305    
306        /**
307         * Performs a login attempt for this Subject/user.  If unsuccessful,
308         * an {@link AuthenticationException} is thrown, the subclass of which identifies why the attempt failed.
309         * If successful, the account data associated with the submitted principals/credentials will be
310         * associated with this {@code Subject} and the method will return quietly.
311         * <p/>
312         * Upon returning quietly, this {@code Subject} instance can be considered
313         * authenticated and {@link #getPrincipal() getPrincipal()} will be non-null and
314         * {@link #isAuthenticated() isAuthenticated()} will be {@code true}.
315         *
316         * @param token the token encapsulating the subject's principals and credentials to be passed to the
317         *              Authentication subsystem for verification.
318         * @throws org.apache.shiro.authc.AuthenticationException
319         *          if the authentication attempt fails.
320         * @since 0.9
321         */
322        void login(AuthenticationToken token) throws AuthenticationException;
323    
324        /**
325         * Returns {@code true} if this Subject/user proved their identity <em>during their current session</em>
326         * by providing valid credentials matching those known to the system, {@code false} otherwise.
327         * <p/>
328         * Note that even if this Subject's identity has been remembered via 'remember me' services, this method will
329         * still return {@code false} unless the user has actually logged in with proper credentials <em>during their
330         * current session</em>.  See the {@link #isRemembered() isRemembered()} method JavaDoc for more.
331         *
332         * @return {@code true} if this Subject proved their identity during their current session
333         *         by providing valid credentials matching those known to the system, {@code false} otherwise.
334         * @since 0.9
335         */
336        boolean isAuthenticated();
337    
338    
339        /**
340         * Returns {@code true} if this {@code Subject} has an identity (it is not anonymous) and the identity
341         * (aka {@link #getPrincipals() principals}) is remembered from a successful authentication during a previous
342         * session.
343         * <p/>
344         * Although the underlying implementation determines exactly how this method functions, most implementations have
345         * this method act as the logical equivalent to this code:
346         * <pre>
347         * {@link #getPrincipal() getPrincipal()} != null && !{@link #isAuthenticated() isAuthenticated()}</pre>
348         * <p/>
349         * Note as indicated by the above code example, if a {@code Subject} is remembered, they are
350         * <em>NOT</em> considered authenticated.  A check against {@link #isAuthenticated() isAuthenticated()} is a more
351         * strict check than that reflected by this method.  For example, a check to see if a subject can access financial
352         * information should almost always depend on {@link #isAuthenticated() isAuthenticated()} to <em>guarantee</em> a
353         * verified identity, and not this method.
354         * <p/>
355         * Once the subject is authenticated, they are no longer considered only remembered because their identity would
356         * have been verified during the current session.
357         * <h4>Remembered vs Authenticated</h4>
358         * Authentication is the process of <em>proving</em> you are who you say you are.  When a user is only remembered,
359         * the remembered identity gives the system an idea who that user probably is, but in reality, has no way of
360         * absolutely <em>guaranteeing</em> if the remembered {@code Subject} represents the user currently
361         * using the application.
362         * <p/>
363         * So although many parts of the application can still perform user-specific logic based on the remembered
364         * {@link #getPrincipals() principals}, such as customized views, it should never perform highly-sensitive
365         * operations until the user has legitimately verified their identity by executing a successful authentication
366         * attempt.
367         * <p/>
368         * We see this paradigm all over the web, and we will use <a href="http://www.amazon.com">Amazon.com</a> as an
369         * example:
370         * <p/>
371         * When you visit Amazon.com and perform a login and ask it to 'remember me', it will set a cookie with your
372         * identity.  If you don't log out and your session expires, and you come back, say the next day, Amazon still knows
373         * who you <em>probably</em> are: you still see all of your book and movie recommendations and similar user-specific
374         * features since these are based on your (remembered) user id.
375         * <p/>
376         * BUT, if you try to do something sensitive, such as access your account's billing data, Amazon forces you
377         * to do an actual log-in, requiring your username and password.
378         * <p/>
379         * This is because although amazon.com assumed your identity from 'remember me', it recognized that you were not
380         * actually authenticated.  The only way to really guarantee you are who you say you are, and therefore allow you
381         * access to sensitive account data, is to force you to perform an actual successful authentication.  You can
382         * check this guarantee via the {@link #isAuthenticated() isAuthenticated()} method and not via this method.
383         *
384         * @return {@code true} if this {@code Subject}'s identity (aka {@link #getPrincipals() principals}) is
385         *         remembered from a successful authentication during a previous session, {@code false} otherwise.
386         * @since 1.0
387         */
388        boolean isRemembered();
389    
390        /**
391         * Returns the application {@code Session} associated with this Subject.  If no session exists when this
392         * method is called, a new session will be created, associated with this Subject, and then returned.
393         *
394         * @return the application {@code Session} associated with this Subject.
395         * @see #getSession(boolean)
396         * @since 0.2
397         */
398        Session getSession();
399    
400        /**
401         * Returns the application {@code Session} associated with this Subject.  Based on the boolean argument,
402         * this method functions as follows:
403         * <ul>
404         * <li>If there is already an existing session associated with this {@code Subject}, it is returned and
405         * the {@code create} argument is ignored.</li>
406         * <li>If no session exists and {@code create} is {@code true}, a new session will be created, associated with
407         * this {@code Subject} and then returned.</li>
408         * <li>If no session exists and {@code create} is {@code false}, {@code null} is returned.</li>
409         * </ul>
410         *
411         * @param create boolean argument determining if a new session should be created or not if there is no existing session.
412         * @return the application {@code Session} associated with this {@code Subject} or {@code null} based
413         *         on the above described logic.
414         * @since 0.2
415         */
416        Session getSession(boolean create);
417    
418        /**
419         * Logs out this Subject and invalidates and/or removes any associated entities,
420         * such as a {@link Session Session} and authorization data.  After this method is called, the Subject is
421         * considered 'anonymous' and may continue to be used for another log-in if desired.
422         * <h3>Web Environment Warning</h3>
423         * Calling this method in web environments will usually remove any associated session cookie as part of
424         * session invalidation.  Because cookies are part of the HTTP header, and headers can only be set before the
425         * response body (html, image, etc) is sent, this method in web environments must be called before <em>any</em>
426         * content has been rendered.
427         * <p/>
428         * The typical approach most applications use in this scenario is to redirect the user to a different
429         * location (e.g. home page) immediately after calling this method.  This is an effect of the HTTP protocol
430         * itself and not a reflection of Shiro's implementation.
431         * <p/>
432         * Non-HTTP environments may of course use a logged-out subject for login again if desired.
433         */
434        void logout();
435    
436        /**
437         * Associates the specified {@code Callable} with this {@code Subject} instance and then executes it on the
438         * currently running thread.  If you want to execute the {@code Callable} on a different thread, it is better to
439         * use the {@link #associateWith(Callable)} method instead.
440         *
441         * @param callable the Callable to associate with this subject and then execute.
442         * @param <V>      the type of return value the {@code Callable} will return
443         * @return the resulting object returned by the {@code Callable}'s execution.
444         * @throws ExecutionException if the {@code Callable}'s {@link Callable#call call} method throws an exception.
445         * @since 1.0
446         */
447        <V> V execute(Callable<V> callable) throws ExecutionException;
448    
449        /**
450         * Associates the specified {@code Runnable} with this {@code Subject} instance and then executes it on the
451         * currently running thread.  If you want to execute the {@code Runnable} on a different thread, it is better to
452         * use the {@link #associateWith(Runnable)} method instead.
453         * <p/>
454         * <b>Note</b>: This method is primarily provided to execute existing/legacy Runnable implementations.  It is better
455         * for new code to use {@link #execute(Callable)} since that supports the ability to return values and catch
456         * exceptions.
457         *
458         * @param runnable the {@code Runnable} to associate with this {@code Subject} and then execute.
459         * @since 1.0
460         */
461        void execute(Runnable runnable);
462    
463        /**
464         * Returns a {@code Callable} instance matching the given argument while additionally ensuring that it will
465         * retain and execute under this Subject's identity.  The returned object can be used with an
466         * {@link java.util.concurrent.ExecutorService ExecutorService} to execute as this Subject.
467         * <p/>
468         * This will effectively ensure that any calls to
469         * {@code SecurityUtils}.{@link SecurityUtils#getSubject() getSubject()} and related functionality will continue
470         * to function properly on any thread that executes the returned {@code Callable} instance.
471         *
472         * @param callable the callable to execute as this {@code Subject}
473         * @param <V>      the {@code Callable}s return value type
474         * @return a {@code Callable} that can be run as this {@code Subject}.
475         * @since 1.0
476         */
477        <V> Callable<V> associateWith(Callable<V> callable);
478    
479        /**
480         * Returns a {@code Runnable} instance matching the given argument while additionally ensuring that it will
481         * retain and execute under this Subject's identity.  The returned object can be used with an
482         * {@link java.util.concurrent.Executor Executor} or another thread to execute as this Subject.
483         * <p/>
484         * This will effectively ensure that any calls to
485         * {@code SecurityUtils}.{@link SecurityUtils#getSubject() getSubject()} and related functionality will continue
486         * to function properly on any thread that executes the returned {@code Runnable} instance.
487         * <p/>
488         * *Note that if you need a return value to be returned as a result of the runnable's execution or if you need to
489         * react to any Exceptions, it is highly recommended to use the
490         * {@link #associateWith(java.util.concurrent.Callable) createCallable} method instead of this one.
491         *
492         * @param runnable the runnable to execute as this {@code Subject}
493         * @return a {@code Runnable} that can be run as this {@code Subject} on another thread.
494         * @see #associateWith (java.util.concurrent.Callable)
495         * @since 1.0
496         */
497        Runnable associateWith(Runnable runnable);
498    
499        /**
500         * Allows this subject to 'run as' or 'assume' another identity indefinitely.  This can only be
501         * called when the {@code Subject} instance already has an identity (i.e. they are remembered from a previous
502         * log-in or they have authenticated during their current session).
503         * <p/>
504         * Some notes about {@code runAs}:
505         * <ul>
506         * <li>You can tell if a {@code Subject} is 'running as' another identity by calling the
507         * {@link #isRunAs() isRunAs()} method.</li>
508         * <li>If running as another identity, you can determine what the previous 'pre run as' identity
509         * was by calling the {@link #getPreviousPrincipals() getPreviousPrincipals()} method.</li>
510         * <li>When you want a {@code Subject} to stop running as another identity, you can return to its previous
511         * 'pre run as' identity by calling the {@link #releaseRunAs() releaseRunAs()} method.</li>
512         * </ul>
513         *
514         * @param principals the identity to 'run as', aka the identity to <em>assume</em> indefinitely.
515         * @throws NullPointerException  if the specified principals collection is {@code null} or empty.
516         * @throws IllegalStateException if this {@code Subject} does not yet have an identity of its own.
517         * @since 1.0
518         */
519        void runAs(PrincipalCollection principals) throws NullPointerException, IllegalStateException;
520    
521        /**
522         * Returns {@code true} if this {@code Subject} is 'running as' another identity other than its original one or
523         * {@code false} otherwise (normal {@code Subject} state).  See the {@link #runAs runAs} method for more
524         * information.
525         *
526         * @return {@code true} if this {@code Subject} is 'running as' another identity other than its original one or
527         *         {@code false} otherwise (normal {@code Subject} state).
528         * @see #runAs
529         * @since 1.0
530         */
531        boolean isRunAs();
532    
533        /**
534         * Returns the previous 'pre run as' identity of this {@code Subject} before assuming the current
535         * {@link #runAs runAs} identity, or {@code null} if this {@code Subject} is not operating under an assumed
536         * identity (normal state). See the {@link #runAs runAs} method for more information.
537         *
538         * @return the previous 'pre run as' identity of this {@code Subject} before assuming the current
539         *         {@link #runAs runAs} identity, or {@code null} if this {@code Subject} is not operating under an assumed
540         *         identity (normal state).
541         * @see #runAs
542         * @since 1.0
543         */
544        PrincipalCollection getPreviousPrincipals();
545    
546        /**
547         * Releases the current 'run as' (assumed) identity and reverts back to the previous 'pre run as'
548         * identity that existed before {@code #runAs runAs} was called.
549         * <p/>
550         * This method returne 'run as' (assumed) identity being released or {@code null} if this {@code Subject} is not
551         * operating under an assumed identity.
552         *
553         * @return the 'run as' (assumed) identity being released or {@code null} if this {@code Subject} is not operating
554         *         under an assumed identity.
555         * @see #runAs
556         * @since 1.0
557         */
558        PrincipalCollection releaseRunAs();
559    
560        /**
561         * Builder design pattern implementation for creating {@link Subject} instances in a simplified way without
562         * requiring knowledge of Shiro's construction techniques.
563         * <p/>
564         * <b>NOTE</b>: This is provided for framework development support only and should typically never be used by
565         * application developers.  {@code Subject} instances should generally be acquired by using
566         * <code>SecurityUtils.{@link SecurityUtils#getSubject() getSubject()}</code>
567         * <h4>Usage</h4>
568         * The simplest usage of this builder is to construct an anonymous, session-less {@code Subject} instance:
569         * <pre>
570         * Subject subject = new Subject.{@link #Builder() Builder}().{@link #buildSubject() buildSubject()};</pre>
571         * The default, no-arg {@code Subject.Builder()} constructor shown above will use the application's
572         * currently accessible {@code SecurityManager} via
573         * <code>SecurityUtils.{@link SecurityUtils#getSecurityManager() getSecurityManager()}</code>.  You may also
574         * specify the exact {@code SecurityManager} instance to be used by the additional
575         * <code>Subject.{@link #Builder(org.apache.shiro.mgt.SecurityManager) Builder(securityManager)}</code>
576         * constructor if desired.
577         * <p/>
578         * All other methods may be called before the {@link #buildSubject() buildSubject()} method to
579         * provide context on how to construct the {@code Subject} instance.  For example, if you have a session id and
580         * want to acquire the {@code Subject} that 'owns' that session (assuming the session exists and is not expired):
581         * <pre>
582         * Subject subject = new Subject.Builder().sessionId(sessionId).buildSubject();</pre>
583         * <p/>
584         * Similarly, if you want a {@code Subject} instance reflecting a certain identity:
585         * <pre>
586         * PrincipalCollection principals = new SimplePrincipalCollection("username", <em>yourRealmName</em>);
587         * Subject subject = new Subject.Builder().principals(principals).build();</pre>
588         * <p/>
589         * <b>Note*</b> that the returned {@code Subject} instance is <b>not</b> automatically bound to the application (thread)
590         * for further use.  That is,
591         * {@link org.apache.shiro.SecurityUtils SecurityUtils}.{@link org.apache.shiro.SecurityUtils#getSubject() getSubject()}
592         * will not automatically return the same instance as what is returned by the builder.  It is up to the framework
593         * developer to bind the built {@code Subject} for continued use if desired.
594         *
595         * @since 1.0
596         */
597        public static class Builder {
598    
599            /**
600             * Hold all contextual data via the Builder instance's method invocations to be sent to the
601             * {@code SecurityManager} during the {@link #buildSubject} call.
602             */
603            private final SubjectContext subjectContext;
604    
605            /**
606             * The SecurityManager to invoke during the {@link #buildSubject} call.
607             */
608            private final SecurityManager securityManager;
609    
610            /**
611             * Constructs a new {@link Subject.Builder} instance, using the {@code SecurityManager} instance available
612             * to the calling code as determined by a call to {@link org.apache.shiro.SecurityUtils#getSecurityManager()}
613             * to build the {@code Subject} instance.
614             */
615            public Builder() {
616                this(SecurityUtils.getSecurityManager());
617            }
618    
619            /**
620             * Constructs a new {@link Subject.Builder} instance which will use the specified {@code SecurityManager} when
621             * building the {@code Subject} instance.
622             *
623             * @param securityManager the {@code SecurityManager} to use when building the {@code Subject} instance.
624             */
625            public Builder(SecurityManager securityManager) {
626                if (securityManager == null) {
627                    throw new NullPointerException("SecurityManager method argument cannot be null.");
628                }
629                this.securityManager = securityManager;
630                this.subjectContext = newSubjectContextInstance();
631                if (this.subjectContext == null) {
632                    throw new IllegalStateException("Subject instance returned from 'newSubjectContextInstance' " +
633                            "cannot be null.");
634                }
635                this.subjectContext.setSecurityManager(securityManager);
636            }
637    
638            /**
639             * Creates a new {@code SubjectContext} instance to be used to populate with subject contextual data that
640             * will then be sent to the {@code SecurityManager} to create a new {@code Subject} instance.
641             *
642             * @return a new {@code SubjectContext} instance
643             */
644            protected SubjectContext newSubjectContextInstance() {
645                return new DefaultSubjectContext();
646            }
647    
648            /**
649             * Returns the backing context used to build the {@code Subject} instance, available to subclasses
650             * since the {@code context} class attribute is marked as {@code private}.
651             *
652             * @return the backing context used to build the {@code Subject} instance, available to subclasses.
653             */
654            protected SubjectContext getSubjectContext() {
655                return this.subjectContext;
656            }
657    
658            /**
659             * Enables building a {@link Subject Subject} instance that owns the {@link Session Session} with the
660             * specified {@code sessionId}.
661             * <p/>
662             * Usually when specifying a {@code sessionId}, no other {@code Builder} methods would be specified because
663             * everything else (principals, inet address, etc) can usually be reconstructed based on the referenced
664             * session alone.  In other words, this is almost always sufficient:
665             * <pre>
666             * new Subject.Builder().sessionId(sessionId).buildSubject();</pre>
667             * <p/>
668             * <b>Although simple in concept, this method provides very powerful functionality previously absent in almost
669             * all Java environments:</b>
670             * <p/>
671             * The ability to reference a {@code Subject} and their server-side session
672             * <em>across clients of different mediums</em> such as web applications, Java applets,
673             * standalone C# clients over XML-RPC and/or SOAP, and many others. This is a <em>huge</em>
674             * benefit in heterogeneous enterprise applications.
675             * <p/>
676             * To maintain session integrity across client mediums, the {@code sessionId} <b>must</b> be transmitted
677             * to all client mediums securely (e.g. over SSL) to prevent man-in-the-middle attacks.  This
678             * is nothing new - all web applications are susceptible to the same problem when transmitting
679             * {@code Cookie}s or when using URL rewriting.  As long as the
680             * {@code sessionId} is transmitted securely, session integrity can be maintained.
681             *
682             * @param sessionId the id of the session that backs the desired Subject being acquired.
683             * @return this {@code Builder} instance for method chaining.
684             */
685            public Builder sessionId(Serializable sessionId) {
686                if (sessionId != null) {
687                    this.subjectContext.setSessionId(sessionId);
688                }
689                return this;
690            }
691    
692            /**
693             * Ensures the {@code Subject} being built will reflect the specified host name or IP as its originating
694             * location.
695             *
696             * @param host the host name or IP address to use as the {@code Subject}'s originating location.
697             * @return this {@code Builder} instance for method chaining.
698             */
699            public Builder host(String host) {
700                if (StringUtils.hasText(host)) {
701                    this.subjectContext.setHost(host);
702                }
703                return this;
704            }
705    
706            /**
707             * Ensures the {@code Subject} being built will use the specified {@link Session} instance.  Note that it is
708             * more common to use the {@link #sessionId sessionId} builder method rather than having to construct a
709             * {@code Session} instance for this method.
710             *
711             * @param session the session to use as the {@code Subject}'s {@link Session}
712             * @return this {@code Builder} instance for method chaining.
713             */
714            public Builder session(Session session) {
715                if (session != null) {
716                    this.subjectContext.setSession(session);
717                }
718                return this;
719            }
720    
721            /**
722             * Ensures the {@code Subject} being built will reflect the specified principals (aka identity).
723             * <p/>
724             * For example, if your application's unique identifier for users is a {@code String} username, and you wanted
725             * to create a {@code Subject} instance that reflected a user whose username is
726             * '{@code jsmith}', and you knew the Realm that could acquire {@code jsmith}'s principals based on the username
727             * was named &quot;{@code myRealm}&quot;, you might create the '{@code jsmith} {@code Subject} instance this
728             * way:
729             * <pre>
730             * PrincipalCollection identity = new {@link org.apache.shiro.subject.SimplePrincipalCollection#SimplePrincipalCollection(Object, String) SimplePrincipalCollection}(&quot;jsmith&quot;, &quot;myRealm&quot;);
731             * Subject jsmith = new Subject.Builder().principals(identity).buildSubject();</pre>
732             * <p/>
733             * Similarly, if your application's unique identifier for users is a {@code long} value (such as might be used
734             * as a primary key in a relational database) and you were using a {@code JDBC}
735             * {@code Realm} named, (unimaginatively) &quot;jdbcRealm&quot;, you might create the Subject
736             * instance this way:
737             * <pre>
738             * long userId = //get user ID from somewhere
739             * PrincipalCollection userIdentity = new {@link org.apache.shiro.subject.SimplePrincipalCollection#SimplePrincipalCollection(Object, String) SimplePrincipalCollection}(<em>userId</em>, &quot;jdbcRealm&quot;);
740             * Subject user = new Subject.Builder().principals(identity).buildSubject();</pre>
741             *
742             * @param principals the principals to use as the {@code Subject}'s identity.
743             * @return this {@code Builder} instance for method chaining.
744             */
745            public Builder principals(PrincipalCollection principals) {
746                if (!CollectionUtils.isEmpty(principals)) {
747                    this.subjectContext.setPrincipals(principals);
748                }
749                return this;
750            }
751    
752            /**
753             * Ensures the {@code Subject} being built will be considered
754             * {@link org.apache.shiro.subject.Subject#isAuthenticated() authenticated}.  Per the
755             * {@link org.apache.shiro.subject.Subject#isAuthenticated() isAuthenticated()} JavaDoc, be careful
756             * when specifying {@code true} - you should know what you are doing and have a good reason for ignoring Shiro's
757             * default authentication state mechanisms.
758             *
759             * @param authenticated whether or not the built {@code Subject} will be considered authenticated.
760             * @return this {@code Builder} instance for method chaining.
761             * @see org.apache.shiro.subject.Subject#isAuthenticated()
762             */
763            public Builder authenticated(boolean authenticated) {
764                this.subjectContext.setAuthenticated(authenticated);
765                return this;
766            }
767    
768            /**
769             * Allows custom attributes to be added to the underlying context {@code Map} used to construct the
770             * {@link Subject} instance.
771             * <p/>
772             * A {@code null} key throws an {@link IllegalArgumentException}. A {@code null} value effectively removes
773             * any previously stored attribute under the given key from the context map.
774             * <p/>
775             * <b>*NOTE*:</b> This method is only useful when configuring Shiro with a custom {@link SubjectFactory}
776             * implementation.  This method allows end-users to append additional data to the context map which the
777             * {@code SubjectFactory} implementation can use when building custom Subject instances. As such, this method
778             * is only useful when a custom {@code SubjectFactory} implementation has been configured.
779             *
780             * @param attributeKey   the key under which the corresponding value will be stored in the context {@code Map}.
781             * @param attributeValue the value to store in the context map under the specified {@code attributeKey}.
782             * @return this {@code Builder} instance for method chaining.
783             * @throws IllegalArgumentException if the {@code attributeKey} is {@code null}.
784             * @see SubjectFactory#createSubject(SubjectContext)
785             */
786            @SuppressWarnings({"UnusedDeclaration"})
787            public Builder contextAttribute(String attributeKey, Object attributeValue) {
788                if (attributeKey == null) {
789                    String msg = "Subject context map key cannot be null.";
790                    throw new IllegalArgumentException(msg);
791                }
792                if (attributeValue == null) {
793                    this.subjectContext.remove(attributeKey);
794                } else {
795                    this.subjectContext.put(attributeKey, attributeValue);
796                }
797                return this;
798            }
799    
800            /**
801             * Creates and returns a new {@code Subject} instance reflecting the cumulative state acquired by the
802             * other methods in this class.
803             * <p/>
804             * This {@code Builder} instance will still retain the underlying state after this method is called - it
805             * will not clear it; repeated calls to this method will return multiple {@link Subject} instances, all
806             * reflecting the exact same state.  If a new (different) {@code Subject} is to be constructed, a new
807             * {@code Builder} instance must be created.
808             * <p/>
809             * <b>Note</b> that the returned {@code Subject} instance is <b>not</b> automatically bound to the application
810             * (thread) for further use.  That is,
811             * {@link org.apache.shiro.SecurityUtils SecurityUtils}.{@link org.apache.shiro.SecurityUtils#getSubject() getSubject()}
812             * will not automatically return the same instance as what is returned by the builder.  It is up to the
813             * framework developer to bind the returned {@code Subject} for continued use if desired.
814             *
815             * @return a new {@code Subject} instance reflecting the cumulative state acquired by the
816             *         other methods in this class.
817             */
818            public Subject buildSubject() {
819                return this.securityManager.createSubject(this.subjectContext);
820            }
821        }
822    
823    }