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