Announcement Announcement Module
Collapse
No announcement yet.
authz:authentication question Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • authz:authentication question

    I've been working with ACEGI for only a week and I've already produced some good results but I can't manage to put the classic "Hello FirstName LastName" in all JSP Pages, it works fine with the username using authz:authentication tag though. I'd love to know how can I do to use other properties like FirstName and LastName. In the doc I've read that the authz tag can't do it.

    Thanks!

  • #2
    The answer to your question greatly depends upon your implementation, but I'll give you an example from my evolving implementation.

    Conceptually, the ContextHolder should contain a SecureContext or some derivative. With that being the case, you can get the SecureContext instance and then query it for its authentication. The authentication may or may not exist. If it does exist, then you can query the authentication to get its principal. The returned value of this call is either a String, a UserDetails instance, or some other instance of a class that you have defined (something that has implemented UserDetails and extended beyond).

    In my case, I have a User class which implements UserDetails and extends this functionality to provide additional user profile details (e.g. name, last name, etc.).

    So basically that's how you'd get to your principle information. Next you have a choice of where to put this accessing code. You could put these gory details in your JSP page, but that is probably not the preferred method. What I have done is written a method which exists in an abstract controller which basically returns a user and then my controller returns this instance as part of the model. The method could be refactored into a utilities class for more widespread use and I may do that once things settle out.

    Anyway, here's the method:

    Code:
      /**
       * Retrieves a User instance from a secure context.  If there is no authentication
       * returns null.
       * @return the authenticated User instance or null if not authenticated.
       */
      protected User getUserFromContext()
      {
        if ((ContextHolder.getContext() == null)
            || !(ContextHolder.getContext() instanceof SecureContext)
            || (((SecureContext) ContextHolder.getContext()).getAuthentication() == null))
        {
          return null;
        }
    
        Authentication auth = ((SecureContext) ContextHolder.getContext()).getAuthentication();
    
        if (auth.getPrincipal() == null)
        {
          return null;
        }
        else if (auth.getPrincipal() instanceof User)
        {
          return (User) auth.getPrincipal();
        }
        else
        {
          return null;
        }
      }
    And the controller code which uses this:

    Code:
      public ModelAndView handleRequest(HttpServletRequest httpServletRequest,
                                        HttpServletResponse httpServletResponse) throws Exception
      {
        return new ModelAndView(memberView, USER, getUserFromContext());
      }
    And this allows your JSP code to do this:

    Code:
    <%@ include file="/WEB-INF/views/inc/taglibs.jsp" %>
    <html>
      <head>
        <title>Member Home</title>
      </head>
      <body>
        Welcome $&#123;user.name&#125; $&#123;user.lastName&#125;
      </body>
    </html>
    Hope this helps, but be careful as you are not guaranteed to have a User in your authentication. If you have anonymous authentication in play, this could complicate things. Also, I did not add any null checking within the JSP, so you'd probably add that. But fundamentally, this is representative of code that could be evolved to work.

    Bill

    Comment


    • #3
      If using HttpSessionContextIntegrationFilter, irrespective of whether the user has logged in or not there should be a non-null SecureContext implementation in the ContextHolder.

      As such you can shortcut a bit of casting by using SecureContextUtils.getSecureContext().

      Comment


      • #4
        Thank you very much... That helps a lot, I also have a User implementation with the additional details (name, e-mail,etc.). The only problem I see is the use of a Controller because I want to display first and last name in all JSP pages, not in a concrete request... I've just thought of making an abstract controller that gets the user and then calls a template method that all concrete controllers redefine with their concrete behaviour...I'll see...

        Comment


        • #5
          You can directly access the ContextHolder from a JSP, or write a taglib to do that. See net.sf.acegisecurity.taglibs.authz.AuthenticationT ag for instance.

          Comment


          • #6
            Updating the example to the current classnames to help someone in the future.

            The classnames have changed since this was posted. I thought I'd update it to make it a more current (as of Spring 2.0.2)

            Code:
            import org.acegisecurity.Authentication;
            import org.acegisecurity.context.SecurityContext;
            import org.acegisecurity.context.SecurityContextHolder;
            import org.acegisecurity.userdetails.UserDetails;
            
            
            <snip>
            ...
            </snip>
            
            
             	/**
            	 * Retrieves a User instance from a secure context. If there is no
            	 * authentication returns null.
            	 * 
            	 * @return the authenticated User instance or null if not authenticated.
            	 */
            	protected UserDetails getUserFromContext() {
            		if ((SecurityContextHolder.getContext() == null)
            				|| !(SecurityContextHolder.getContext() instanceof SecurityContext)
            				|| (((SecurityContext) SecurityContextHolder.getContext())
            						.getAuthentication() == null)) {
            			return null;
            		}
            
            		Authentication auth = ((SecurityContext) SecurityContextHolder
            				.getContext()).getAuthentication();
            
            		if (auth.getPrincipal() == null) {
            			return null;
            		} else if (auth.getPrincipal() instanceof UserDetails) {
            			return (UserDetails) auth.getPrincipal();
            		} else {
            			return null;
            		}
            	}

            Comment

            Working...
            X