Page 1 of 2 12 LastLast
Results 1 to 10 of 17

Thread: Supported Way to Emulate request.getUserPrincipal?

  1. #1
    Join Date
    Aug 2004
    Location
    Hawaii, US
    Posts
    225

    Default Supported Way to Emulate request.getUserPrincipal?

    Hello,

    I'm trying to migrate our application to use Acegi. I can't seem to find a supported way for request.getUserPrincipal to work. Is there a filter impl that wraps a normal HttpServletRequest with one that would make getUserPrincipal return info?

    Thanks very much,
    Seth

  2. #2
    Join Date
    Aug 2004
    Posts
    229

    Default

    IIRC, I believe this is handled by container integration. Basically, custom integration code for each type of container (Tomcat, JBoss, WebLogic, etc) must be maintained. I'm not sure what the status of this maintenance is for Acegi. At one point it was bundled with Acegi, but it may have been split off by now. At any rate, it is handled by a filter (filters extending AbstractIntegrationFilter in my version of Acegi). In the worst case you would have to end up extending AbstractIntegrationFilter yourself to integrate with your container - but I bet this wouldn't be too hard.

    - Andy

  3. #3
    Join Date
    Aug 2004
    Location
    Hawaii, US
    Posts
    225

    Default

    Thanks your your reply!

    I was under the impression that the container integration code was useful when you needed the container to do the authentication.

    I have migrated to Acegi for Authentication, so I have a SecureContext available to me. I wanted to get that into the HttpServletRequest to ease migration, porting, and to keep Acegi code out of my Servlets and Controllers. I think this is the opposite intent of the container integration code (where you have a good request.getUserPrincipal, but you need to push into a SecureContext).

    Of course, I could be totally wrong here. I'll double check now.

    In any case, I did end up creating a simple filter that creates a HttpServletRequestWrapper and replaces the calls to getUserPrincipal, isUserInRole, etc with methods that delegate to my SecureContext and Authentication objects.

    It seems like this would be very useful, especially as it brings Acegi closer to a "drop-in" replacement for container auth. I'd be happy to donate this (very simple) code.

  4. #4
    Join Date
    Aug 2004
    Location
    Hawaii, US
    Posts
    225

    Default

    The simple wrapper for the HttpServletRequest seems to be working quite well. I'd love any feedback, and if so, for this to be included in the next release of Acegi. I think it's a great step forward to making it possible for Acegi to be a "drop-in" replacement.

    Code:
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    
    import net.sf.acegisecurity.context.ContextHolder;
    import net.sf.acegisecurity.context.SecureContext;
    
    /**
     * Wraps a normal <code>HttpServletRequest</code> with a
     * &#123;@link AuthenticationHttpServletRequest&#125;.
     * <p/>
     * This helps with transparent migration from old container managed code
     * that relied on calls such as <code>request.getUserPrincipal</code> to
     * the Acegi framework.
     */
    public class AuthenticationWrapperFilter implements Filter &#123;
    
        /**
         * @see javax.servlet.Filter#init&#40;javax.servlet.FilterConfig&#41;
         */
        public void init&#40;FilterConfig arg0&#41; throws ServletException &#123; &#125;
    
        /**
         * @see javax.servlet.Filter#doFilter&#40;javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain&#41;
         */
        public void doFilter&#40;ServletRequest req, ServletResponse res,
                FilterChain chain&#41; throws IOException, ServletException &#123;
            SecureContext ctx = &#40;SecureContext&#41; ContextHolder.getContext&#40;&#41;;
            ServletRequest oldReq = null;
            
            if &#40;isValidContext&#40;ctx&#41;&#41; &#123;
                oldReq = req;
                req = new AuthenticationHttpServletRequest&#40;&#40;HttpServletRequest&#41;req&#41;;
            &#125;
            
            chain.doFilter&#40;req, res&#41;;
            
            if &#40;isValidContext&#40;ctx&#41;&#41; &#123;
                req = oldReq;
            &#125;
        &#125;
    
        /**
         * @param ctx the current context
         * @return <code>true</code> if the context is not null and it has an
         * <code>Authentication</code> object, or <code>false</code>
         */
        private boolean isValidContext&#40;SecureContext ctx&#41; &#123;
            return ctx != null && ctx.getAuthentication&#40;&#41; != null;
        &#125;
    
        /**
         * @see javax.servlet.Filter#destroy&#40;&#41;
         */
        public void destroy&#40;&#41; &#123; &#125;
    
    &#125;
    Code:
    import java.security.Principal;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    
    import net.sf.acegisecurity.Authentication;
    import net.sf.acegisecurity.GrantedAuthority;
    import net.sf.acegisecurity.context.ContextHolder;
    import net.sf.acegisecurity.context.SecureContext;
    
    /**
     * Wraps a normal <code>HttpServletRequest</code> to delegate Principal
     * related methods to the <code>Authentication</code> object that lives
     * in the <code>SecureContext</code> of the current Thread.
     * <p/>
     * This helps with transparent migration from old container managed code
     * that relied on calls such as <code>request.getUserPrincipal</code> to
     * the Acegi framework.
     */
    public class AuthenticationHttpServletRequest extends HttpServletRequestWrapper &#123;
        
        private Authentication auth;
    
        /**
         * @param request the original request
         */
        public AuthenticationHttpServletRequest&#40;HttpServletRequest request&#41; &#123;
            super&#40;request&#41;;
            SecureContext ctx = &#40;SecureContext&#41; ContextHolder.getContext&#40;&#41;;
            auth = ctx.getAuthentication&#40;&#41;;
        &#125;
        
        /**
         * @see javax.servlet.http.HttpServletRequest#getRemoteUser&#40;&#41;
         */
        public String getRemoteUser&#40;&#41; &#123;
            return auth.getName&#40;&#41;;
        &#125;
        
        /**
         * @see javax.servlet.http.HttpServletRequest#getUserPrincipal&#40;&#41;
         */
        public Principal getUserPrincipal&#40;&#41; &#123;
            return auth;
        &#125;
        
        /**
         * @see javax.servlet.http.HttpServletRequest#isUserInRole&#40;java.lang.String&#41;
         */
        public boolean isUserInRole&#40;String roleName&#41; &#123;
            if &#40;roleName == null&#41; return false;
            
            GrantedAuthority&#91;&#93; roles = auth.getAuthorities&#40;&#41;;
            for &#40;int i = 0; i < roles.length; i++&#41; &#123;
                if &#40;roleName.equals&#40;roles&#91;i&#93;.getAuthority&#40;&#41;&#41;&#41; &#123;
                    return true;
                &#125;
            &#125;
            
            return false;
        &#125;
    &#125;

  5. #5
    Join Date
    Aug 2004
    Location
    Sydney, Australia
    Posts
    2,768

    Default

    Folks, it's already in release 0.7.0! :-)

    Take a look in the net.sf.acegisecurity.ui.wrapper package. Sorry I didn't get to this post sooner and could have saved you some coding.

  6. #6
    Join Date
    Aug 2004
    Posts
    229

    Default

    Boy, not only was I wrong to begin with, but the code is there in the latest version. Well, thought oughta teach me not to shoot off the hip.

    - Andy

  7. #7
    Join Date
    Aug 2004
    Location
    Hawaii, US
    Posts
    225

    Default

    Thanks Ben!

    I knew it had to be in there, just haven't learned the package layout of Acegi yet.

    Migrating over to the supported code now.

  8. #8
    Join Date
    Aug 2004
    Location
    Hawaii, US
    Posts
    225

    Default

    Hi Ben,

    I took a look at ContextHolderAwareRequestWrapper. It doesn't override getUserPrincipal. I think we can easily provide an implementation for it, by returning the Authentication (which itself is a Principal).

    What do you think?

    Thanks,
    Seth

    ps I tried to sign up for the developers list, but never received my confirmation. Will try again.

  9. #9
    Join Date
    Aug 2004
    Location
    Sydney, Australia
    Posts
    2,768

    Default

    For the benefit of the forum archives, Seth sent in a contribution for this functionality. The patch was added to CVS today.

  10. #10
    Join Date
    Oct 2004
    Location
    Kuala Lumpur
    Posts
    7

    Default How does it work in 0.8?

    Hi all,
    can anybody give me a hint how it's implemented in version 0.8.

    My code was working fine with 0.7, but after I upgraded to 0.8 the isUserInRole doesn't work anymore.

    I added filter ContextHolderAwareRequestFilter - and it works correctly - but only in the filter itself. When UserRoleAuthorizationInterceptor is called the isUserInRole returns false for everything...

    Thanks

    Peter

Similar Threads

  1. Replies: 5
    Last Post: Aug 28th, 2005, 10:28 AM
  2. Replies: 2
    Last Post: May 24th, 2005, 11:22 AM
  3. Replies: 10
    Last Post: Feb 16th, 2005, 11:34 AM
  4. Which Hibernate version supported?
    By Lilly in forum Data
    Replies: 2
    Last Post: Feb 7th, 2005, 07:23 PM
  5. When element "import" will be supported?
    By swisswheel in forum SpringSource Tool Suite
    Replies: 2
    Last Post: Jan 23rd, 2005, 08:53 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •