|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object com.zeevbelkin.web.filter.access.Yaaf
public class Yaaf
This class is an authentication, authorization and access control filter for j2ee web applications. This filter loosely emulates j2ee servlet container role based security with some extensions, it allows to easily implement login procedures for much more complicated user interaction schemes then standard container based security form login procedure. These schemas are required to provide cookie login, openid login, explicit login, etc. The filter is completely compatible with struts. The next terms are used in the documentation:
SavedLoginHandler
.
AjaxLoginPeer
.
The resource may be protected by the next way:
<filter> <filter-name>Yaacfi</filter-name> <filter-class>com.zeevbelkin.web.filter.access.Yaaf</filter-class> <init-param> <param-name>access-restrictions</param-name> <param-value>access-restrictions.xml</param-value> </init-param> <init-param> <param-name>login-handler</param-name> <param-value>/Login.do</param-value> </init-param> </filter>The access restriction file contains number of constraint directives, each from them contains the role list and number of "on" directives those describe the regular expression patterns those matches to the protected URL's. Unlike web.xml url-pattern configuration directive, on directive uses real regular expressions described in Pattern . This is an example of the access restriction file.
<security-constraints> <constraint allow-to-roles="role1,role2"> <on url-pattern="/protected/.*"/> </constraint> <constraint allow-to-roles="admin"> <on url-pattern="/adm/.*"/> </constraint> <!-- nobody should have direct access to JSP's those implement struts actions --> <constraint allow-to-roles="nobody"> <on url-pattern="/actions/.*"/> </constraint> </security-constraints>Note: the filter permits access to a user in a role on an URL only and only if all on directives where the patterns match the URL are enclosed into constraint directives where the role is listed.
The filter keeps info about the user identity, and additional info required to organize the login process,
in a session bean SessionSecurityInfo
(this is the class name and also
the bean name) that implements Principal
interface. This bean may be obtained by the name or by the
getUserPrincipal request method
call.
setName
method call, and, optionally, sets the session user role resolver by
setRoleResolver
call (a global user role resolver may be used
to avoid need in this call). Then, in case of login on demand, the login servlet
calls completeLogin
method to resume the operation, that was
interrupted to authenticate the user (in case of the explicit login,
completeLogin
does nothing).
If you need the explicit login procedure, you should inform the filter about the
location that will be used, by the filter, to start the login process.
To provide this information it is necessary to set login-handler parameter
in the filter configuration directive.
<filter> <filter-name>Yaacfi</filter-name> <filter-class>com.zeevbelkin.web.filter.access.Yaaf</filter-class> <init-param> <param-name>access-restrictions</param-name> <param-value>access-restrictions.xml</param-value> </init-param> <init-param> <param-name>login-handler</param-name> <param-value>/Login.do</param-value> </init-param> </filter> <filter-mapping> <filter-name>Yaacfi</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>The global resolver class can be specified in the web.ini configuration file in the <filter> directive.
<filter> <filter-name>Yaacfi</filter-name> <filter-class>com.zeevbelkin.web.filter.access.Yaaf</filter-class> <init-param> <param-name>userRoleResolver</param-name> <param-value>com.somepackage.UserRoleResolver</param-value> </init-param> .... </filter>The global resolver class must implement
Yaaf.UserRoleResolver
interface.
If the resolver class has a constructor that accepts
ServletContext
parameter, this parameter will be passed while the global resolver instantiation.
When a none authenticated user posts data to an URL that requires authorization and the
login on demand process begins, the filter should preserve the POST request body to restore it
after the user authentication completion. The initial version of the filter preserves this
data in the memory, and the maximum allowed POST request size if 256K. It is possible
to change this value by setting the maxPostSize parameter.
<filter> <filter-name>Yaacfi</filter-name> <filter-class>com.zeevbelkin.web.filter.access.Yaaf</filter-class> ... <init-param> <param-name>maxPostSize</param-name> <!-- the size if kilobytes --> <param-value>256</param-value> </init-param> ... </filter>If a servlet returns HTTP 401-403 codes, the filter begins login on demand interaction. It is possible to suppress this behavior by setting handle403as401 parameter to false.
<filter> <filter-name>Yaacfi</filter-name> <filter-class>com.zeevbelkin.web.filter.access.Yaaf</filter-class> ... <init-param> <param-name>handle403as401</param-name> <param-value>false</param-value> </init-param> ... </filter>Sometimes a user begins a login interaction in one from the browser windows then leaves the window and begins a new interaction in another window. If these login interactions are "on demand", the filter keeps only info on the last resource, access to which required the authorization. Therefore, when a user returns to an old window, to continue a previously left login interaction process, in case of successful authentication, the browser will be redirected to a resource other then the resource, access to which raised the interaction in the current window. Of cause, such behavior is unwanted. To prevent this unwanted behavior the filter assigns a special ID to each "on demand" interaction process. The ID is passed as the yaacfiRqId request bean value to the application. The application should pass this parameter back to the filter using a hidden form variable with the same name (the filter can extract, also, the ID value from the HTTP request referer). Here is an example written with struts.
<html:form action="/Login" method="post"> <table> <tr> <td>Login:</td><td> <html:text property="login"/> </td> </tr> <tr> <td>Password:</td><td> <html:password property="password"/> </td> </tr> <tr> <td> <html:submit/> </td> </tr> </table> <input name="yaacfiRqId" type="hidden" value="<bean:write name="yaacfiRqId" scope="request"/>" /> </html:form>Then, the application can use
isSavedRequestValid
method to be sure that the handled request has been issued from the window from which
the last login interaction was initiated.
public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response ) throws Exception { DynaActionForm dac=(DynaActionForm)form; Yaaf.SessionSecurityInfo ssi=(Yaaf.SessionSecurityInfo)request.getUserPrincipal(); synchronized (ssi.getLock()) { if (ssi.getName()!=null) return mapping.findForward("alreadyLoggedIn"); if (!ssi.isSavedRequestValid(request)) return mapping.findForward("outdatedLoginSequence"); if ("pupkin".equals(dac.getString("login"))&&"stam".equals(dac.getString("password"))) { // Yes, this guy is really Pupkin ... ssi.setName("pupkin"); // Remember the user // to allow to him/her to log in // w/o any explicite action ssi.saveLogin(request,response,365); if (ssi.isExplicitLogin()) { return mapping.findForward("afterExplicitLogin"); } else ssi.completeLogin(request,response); return null; } // failure request.setAttribute("failure","failure"); return mapping.findForward("loginScreen"); } }
Nested Class Summary | |
---|---|
static class |
Yaaf.RegexAccessChecker
This class is an implementation of the UrlAccessChecker
based on using of regular expressions. |
static interface |
Yaaf.RoleResolver
SessionSecurityInfo allows to set to an
authenticated user a particular resolver. |
static class |
Yaaf.SessionSecurityInfo
The filter keeps info about the user identity, and additional info required to organize the login process,
in this session bean that implements also Principal
interface. |
static interface |
Yaaf.UrlAccessChecker
is an interface to a class that checks permissions of a user, roles of which can be obtained with Yaaf.RoleResolver
to access a requested resource. |
static interface |
Yaaf.UserRoleResolver
A class that implements a global role resolver should implements this interface. |
Constructor Summary | |
---|---|
Yaaf()
|
Method Summary | |
---|---|
void |
destroy()
Destroy method for this filter |
void |
doFilter(javax.servlet.ServletRequest request,
javax.servlet.ServletResponse response,
javax.servlet.FilterChain chain)
|
javax.servlet.FilterConfig |
getFilterConfig()
Return the filter configuration object for this filter. |
Yaaf.UserRoleResolver |
getRoleResolver()
returns the global user role resolver |
SavedLoginHandler |
getSavedLoginHandler()
Getter for property savedLoginHandler. |
Yaaf.SessionSecurityInfo |
getSSI(javax.servlet.http.HttpSession ses)
returns SessionSecurityInfo session bean. |
static java.lang.String |
getStackTrace(java.lang.Throwable t)
|
void |
init(javax.servlet.FilterConfig filterConfig)
Init method for this filter |
static void |
log(java.lang.String msg)
|
static void |
log(java.lang.String msg,
java.lang.Throwable t)
|
void |
setFilterConfig(javax.servlet.FilterConfig filterConfig)
Set the filter configuration object for this filter. |
void |
setRoleResolver(Yaaf.UserRoleResolver resolver)
sets the global role resolver |
void |
setSavedLoginHandler(SavedLoginHandler savedLoginHandler)
Setter for property savedLoginHandler. |
java.lang.String |
toString()
Return a String representation of this object. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Constructor Detail |
---|
public Yaaf()
Method Detail |
---|
public Yaaf.SessionSecurityInfo getSSI(javax.servlet.http.HttpSession ses)
SessionSecurityInfo
session bean.
If the session has no such bean, new one will be created and returned.
ses
- the session to obtain the SSI object
public Yaaf.UserRoleResolver getRoleResolver()
public void setRoleResolver(Yaaf.UserRoleResolver resolver)
resolver
- Resolver instance. The resolver class must implement UserRoleResolver
interfacepublic void doFilter(javax.servlet.ServletRequest request, javax.servlet.ServletResponse response, javax.servlet.FilterChain chain) throws java.io.IOException, javax.servlet.ServletException
doFilter
in interface javax.servlet.Filter
request
- The servlet request we are processingresult
- The servlet response we are creatingchain
- The filter chain we are processing
java.io.IOException
- if an input/output error occurs
javax.servlet.ServletException
- if a servlet error occurspublic javax.servlet.FilterConfig getFilterConfig()
public void setFilterConfig(javax.servlet.FilterConfig filterConfig)
filterConfig
- The filter configuration objectpublic void destroy()
destroy
in interface javax.servlet.Filter
public void init(javax.servlet.FilterConfig filterConfig)
init
in interface javax.servlet.Filter
public java.lang.String toString()
toString
in class java.lang.Object
public static java.lang.String getStackTrace(java.lang.Throwable t)
public static void log(java.lang.String msg)
public static void log(java.lang.String msg, java.lang.Throwable t)
public SavedLoginHandler getSavedLoginHandler()
public void setSavedLoginHandler(SavedLoginHandler savedLoginHandler)
savedLoginHandler
- New value of property savedLoginHandler.
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |