Menu

#14 use another implementation of SecurityRequestWrapper

open
None
5
2003-03-19
2003-03-10
No

I made an extension which allows you to choose your
own implementation of SecurityRequestWrapper.

Example:
Suppose we have a special kind of realm in which users
have certain roles in certain groups. If we want to check
if a principal has a certain role, we also have to provide
the group (because the roles of a principal depend on
the group you consider). So
realm.isUserInRole(getUserPrincipal(), role);
becomes
groupRealm.isUserInRole(getUserPrincipal(), role,
group);

This is something which can be nicely done in the
SecurityRequestWrapper, without changing the
interface of SecurityRequestWrapper. The wrapper
implements the isUserInRole(String role) method by
retrieving the group from the request and passing it to
the realm.

Therefore it would be nice to make it possible to use
another implementation of the SecurityRequestWrapper.
This can be done by using a RequestWrapperFactory to
create the SecurityRequestWrapper objects. The
implementation of the specific factory can be configured
in security-filter.xml, which also allows you to pass
some factory-params (name, value).
If no factory is specified in security-filter.xml, a default
factory will return the current implementation of
SecurityRequestWrapper.

Discussion

  • Roel Adriaensens

    diff of changed files

     
  • Roel Adriaensens

    new file: factory interface

     
  • Roel Adriaensens

    new file: default factory implementation

     
  • Max Cooper

    Max Cooper - 2003-03-19
    • assigned_to: nobody --> maxcooper
     
  • Max Cooper

    Max Cooper - 2003-03-19

    Logged In: YES
    user_id=590231

    ABOUT THE FUNCTIONAL REQUIREMENTS:

    I see that having a more flexible schema for the users and
    roles/groups would be nice for some applications. The one you
    describe seems like it would apply to many different situations.

    However, the users and roles (a.k.a. groups) structure is well
    established and baked into many, many systems. Fortunately, it
    is very easy to map the schema you desire to the established
    system.

    "user", "group", "role" -- maps to --> "user", "group.role"

    By doing this mapping, you can use all the existing realm
    implementations, security frameworks, etc. without having to
    change anything.

    Does that meet your needs?

    ABOUT THE IMPLEMENTATION METHOD:

    One issue with changing/extending the request interface is that
    you aren't always going to get what you expect. Consider a case
    where you have two filters deployed -- SecurityFilter and another
    filter that does logging or something, call it LoggingFilter. If a
    request comes in, it will be handled by SecurityFilter, and passed
    down the chain with a SecurityRequestWrapper wrapped request
    object. Then LoggingFilter gets it, wraps the request again in
    LoggingRequestWrapper and then finally it arrives at a servlet or
    JSP in the app. If the app tries to cast the request it gets to
    SecurityRequestWrapper to access some extended functionality,
    you will get a ClassCastException, since the request is really a
    LoggingRequestWrapper. You severely limit your ability to use
    other filters in that scenario, which is kind of at odds with their
    chainable nature. I don't even think you are really guarateed that
    you will get the request object exactly as your last filter wraps it --
    the container may be free to wrap it again if it wants to (though I
    don't think any containers do this).

    Extentions to the HttpServletRequest (or response) interfaces
    have this bad architectural side effect, so I think it is good to
    stick with the standard interfaces. It would be cool if the request
    could sort of gain functionality as it gets wrapped, and all the
    interface extensions would be available, but you lose some of the
    meaning of the wrapping concept that way, so I don't think that
    would really be a good idea after all.

    Here is one architectural solution I thought of for this kind of
    extension: You can have your filter stuff a reference to itself, the
    request wrapper, or some other object that provides extended
    services into the request scope so that you can access it at any
    time after the request passes through the filter. You could have a
    static method on a class somewhere that you pass the request to
    that would dig the reference out of the request and return a
    handle to the service provider object (i.e. the filter, the request
    wrapper, some other object).

    -Max

     

Log in to post a comment.