Because most of these datasources usually contain Subject (a.k.a. User) information such as usernames and passwords, a Realm can act as a pluggable authentication module in a PAM configuration. This allows a Realm to perform both authentication and authorization duties for a single datasource, which caters to the large majority of applications. If for some reason you don't want your Realm implementation to perform authentication duties, you should override the {@link #supports(org.apache.shiro.authc.AuthenticationToken)} method to alwaysreturn false.
Because every application is different, security data such as users and roles can be represented in any number of ways. Shiro tries to maintain a non-intrusive development philosophy whenever possible - it does not require you to implement or extend any User, Group or Role interfaces or classes.
Instead, Shiro allows applications to implement this interface to access environment-specific datasources and data model objects. The implementation can then be plugged in to the application's Shiro configuration. This modular technique abstracts away any environment/modeling details and allows Shiro to be deployed in practically any application environment.
Most users will not implement the Realm interface directly, but will extend one of the subclasses, {@link org.apache.shiro.realm.AuthenticatingRealm AuthenticatingRealm} or {@link org.apache.shiro.realm.AuthorizingRealm}, greatly reducing the effort requird to implement a Realm from scratch.
@author Les Hazlewood @author Jeremy Haile @see org.apache.shiro.realm.CachingRealm CachingRealm @see org.apache.shiro.realm.AuthenticatingRealm AuthenticatingRealm @see org.apache.shiro.realm.AuthorizingRealm AuthorizingRealm @see org.apache.shiro.authc.pam.ModularRealmAuthenticator ModularRealmAuthenticator @since 0.1When a SIP request message is received and a jiplet object is selected for delivery of the request, the container checks if the SIP end point needs to be authenticated. The jip.xml file included with every context specifies the authentication and authorization criteria for all the jiplets in the context. Some jiplets may not have any authentication and authorization criteria, but others may have it. If a jiplet requires authentication and authorization, the SIP end point has not been authenticated and the request message does not contain a Authorization header, the container responds to the request with a UNAUTHORIZED (401) response. If the end point has not been authenticated and an Authorization header is included in the request message for the realm, the realm specified by the jiplet is used to authenticate the user. The container calls the authenticate() method specified by this interface to authenticate. If the SIP end point cannot be authenticated, an UNAUTHORIZED (401) response is sent. If the user is successfully authenticated, the container checks if the user roles to determine if the SIP end-point has the required authorization. If the end point does not have the proper authorization, a FORBIDDEN (403) response is sent. Otherwise, the request is forwarded to the jiplet object.
The jiplet container supports "pluggable authentication modules" (not to be confused with PAM although some of the concepts are similar). That is, it is possible to plugin custom authentication and authorization modules into the jiplet container (configured in server.xml). The jiplet container already comes with a number of pre-defined custom realms but you can plug in your own custom module by creating a class that implements this interface. That way, you can integrate your organization's subscriber database into your jiplet application. @author Amit Chatterjee
Binding
can be used. A block of code is said to be executing within a realm if calling {@link #isCurrent()} from that block returns true. Code reached by callingmethods from that block will execute within the same realm, with the exception of methods on this class that can be used to execute code within a specific realm. Clients can use {@link #syncExec(Runnable)}, {@link #asyncExec(Runnable)}, or {@link #exec(Runnable)} to execute arunnable within this realm. Note that using {@link #syncExec(Runnable)} canlead to deadlocks and should be avoided if the current thread holds any locks.
It is instructive to think about possible implementations of Realm: It can be based on executing on a designated thread such as a UI thread, or based on holding a lock. In the former case, calling syncExec on a realm that is not the current realm will execute the given runnable on a different thread (the designated thread). In the latter case, calling syncExec may execute the given runnable on the calling thread, but calling {@link #asyncExec(Runnable)} will execute the given runnable on a differentthread. Therefore, no assumptions can be made about the thread that will execute arguments to {@link #asyncExec(Runnable)}, {@link #syncExec(Runnable)}, or {@link #exec(Runnable)}.
It is possible that a block of code is executing within more than one realm. This can happen for implementations of Realm that are based on holding a lock but don't use a separate thread to run runnables given to {@link #syncExec(Runnable)}. Realm implementations of this kind should be appropriately documented because it increases the opportunity for deadlock.
Some implementations of {@link IObservable} provide constructors which do nottake a Realm argument and are specified to create the observable instance with the current default realm. The default realm can be set for the currently executing thread by using {@link #runWithDefault(Realm,Runnable)}. Note that the default realm does not have to be the current realm.
Subclasses must override at least one of asyncExec()/syncExec(). For realms based on a designated thread, it may be easier to implement asyncExec and keep the default implementation of syncExec. For realms based on holding a lock, it may be easier to implement syncExec and keep the default implementation of asyncExec.
@since 1.0 @see IObservable
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|