Announcement Announcement Module
No announcement yet.
How to get the error message to velocity. Page Title Module
Move Remove Collapse
This topic is closed
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to get the error message to velocity.

    OK, I'm quite new to Spring and Acegi especially. I'm using velocity for the view.
    So, I have acegi returning me to the correct page when a login fails. The example jsp has this code:
        <c&#58;if test="$&#123;not empty param.login_error&#125;">
          <font color="red">
            Your login attempt was not successful, try again.<BR><BR>
            Reason&#58; <%= &#40;&#40;AuthenticationException&#41; session.getAttribute&#40;AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY&#41;&#41;.getMessage&#40;&#41; %>
    Obviously velocity doesn't have access to the session, so I can't get the message out. Is there a way I can get Acegi to populate a model so I can get the message (as well as determine if there was one - param.login_error)?


  • #2
    You'll need to write a tool, much like the authz tag in Acegi Security, and expose it via a VelocityView subclass that overrides exposeHelpers(Map, HttpServletRequest).


    • #3
      Alternatively, you can create a controller that puts the exception on the model and return the VM you want to show (you can use an AbstractController as it doesn't have to do much). In the vm you can check if the exception is empty and if not, print out the message of the exception. You need to specify that controller instead of the VM in the failureURL of the authenticationProcessingFilter and loginFormUrl of the authenticationEntryPoint. Finally, you need to make sure the controller is not secured by the filterInvocationInterceptor.

      This is how I got around this problem (and be able to put other things in the model in order to show that in the vm).

      public class LogonController extends AbstractController &#123;
      	 * @see org.springframework.web.servlet.mvc.AbstractController#handleRequestInternal&#40;javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse&#41;
      	protected ModelAndView handleRequestInternal&#40;HttpServletRequest request, HttpServletResponse response&#41; throws Exception &#123;
      		Map model = new HashMap&#40;&#41;;
      		// Put the authentication exception on the model.
      		AuthenticationException authenticationException = &#40;AuthenticationException&#41;WebUtils.getSessionAttribute&#40;request, AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY&#41;;
      		if &#40;authenticationException != null&#41; &#123;
      			model.put&#40;"acegiSecurityException", authenticationException&#41;;
      		// Do other stuff
      		// Depending on the exception, return the normal logon page or
      		// the expired password page.
      		String view = "logon/logon";
      		if &#40;authenticationException != null && &#40;authenticationException instanceof PasswordExpiredException&#41;&#41; &#123;
      			view = "logon/expired";
      		return new ModelAndView&#40;view, model&#41;;
          #if &#40;$acegiSecurityException&#41;
            <font color="red">
              Your login attempt was not successful, try again.<BR><BR>
      Cheers, Stefaan.


      • #4
        A nice approach, Steffan.


        • #5

          Could you tell me how to specify that controller instead of the VM? I mean, those properties require a String, not a bean. Do I have to modify something to make it work? Thanks.


          • #6
            OK. I think I figured out how to do it. What I did (and seems it is working is as follows)

            Instead of replacing VM with controller (which will not work since the types mismatch), replacing vm page with URL handeld by the LogonController, which Steffan wrote. Then, it seems everything working fine.



            • #7
              That's possibly, but then you have a strange URL mapping. Instead of doing so, you could change the authenticationFailureUrl of the authentication processing filter:

              	<!-- Authentication through Acegi Security Framework --> 
              	<bean id="authenticationProcessingFilter" class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
              		<property name="authenticationManager"><ref bean="authenticationManager"/></property>
              		<property name="authenticationFailureUrl"><value>/logon.lctrl</value></property>
              		<property name="defaultTargetUrl"><value>/</value></property>
              		<property name="filterProcessesUrl"><value>/logon/j_acegi_security_check</value></property>
              with logon.lctrl being my login controller (I took the .lctrl extention so the security enforcer knows there is no authentication necessary to see the logon page).