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