4

Situation: user is forced to change password when button "Change password" is clicked. This click fires form overridden method onSubmit() (Wicket). In this method:

protected void onSubmit() {

   //changing password by updating it in DB

   // autologin user with changed password in system

   //set response page (wicket style)
    setResponsePage(RestorePasswordPage.class);
}

Actually call setResponsePage(...) is the call to Wicket Component.setResponsePage()

public final <C extends Page> void setResponsePage(final Class<C> cls)
{
    getRequestCycle().setResponsePage(cls);
}

My task was to substitute wicket on Spring security and it was solved - I intercept call to this method in Spring Filter Security Chain (class below is one of the components of this chaing). And can do all the things from code snippet above except one - I don't know how to make redirection to RestorePasswordPage

public class ForgotPasswordForcePasswordChangeEventHandler implements CustomEventHandler {
    public void handle(HttpServletRequest request, HttpServletResponse response) {

       // 1. Extract current customer
       // 2. Extract changed password
       // 3. Updates user through external web service
       // 4. Prepares data for authentication
      // 5. Clears security context to remove current authentication

      //redirect to the same page as in wicket
          HOW???
   }
}

Questions:

  1. Is it any way to get access to Wicket RequestCycle if I got only HttpServletRequest request as input.
  2. Any other way to solve this problem?
Triad sou.
  • 2,969
  • 3
  • 23
  • 27
dim1902
  • 1,706
  • 4
  • 18
  • 31

2 Answers2

3

Wicket supports "bookmarkable" pages – Page classes that have a no-parameter constructor, or just accept a PageParameters object. (PageParameters is an abstraction over query string parameters et al.)

If you do not need customise the page instance being redirected to in code, you can use WebApplication#mountPage inside your WebApplication#init to mount it at a "nice" static URL. You then configure Spring Security to redirect to that URL. IIRC, Spring Security intercepts the request before Wicket gets involved, so there is no need and likely no sane way to access Wicket's request processing.

If you do need parameters in the page you're redirecting to, take a look at the request mapping documentation. Essentially, you give the page a constructor with a PageParameters argument. Using PageParameters, you can always access any paramaters given in a standard query string, and "positional parameters" (unmapped extra URL components) without any configuration. When mounting the page, you can also define "named" parameters (extra URL components that are put into the PageParameters map under predefined names) and whatnot.

millimoose
  • 39,073
  • 9
  • 82
  • 134
  • +1, that's a nice way to decouple Wicket from that Event Handler – Xavi López Sep 30 '11 at 12:43
  • Could you give more details, please? Wicket 1.4.9 is used. To redirect from handler I can use `response.sendRedirect(...)`, that takes string as param. To mount page I use `WebApplication.mountBookmarkablePage(request.getContextPath(), RestorePasswordPage.class))` but this is void method. How to perform redirect correctly? – dim1902 Sep 30 '11 at 15:00
  • 1
    To mount the page, you use `WebApplication.mountBookmarkablePage("/forgot-password", RestorePasswordPage.class);`. To redirect you use `response.sendRedirect(request.getContextPath()+"/forgot-password")`. The path ("/forgot-password") can be chosen freely, it just has to be the same when mounting the page and when doing the redirect. (Preferrably, use a constant.) – millimoose Sep 30 '11 at 15:48
  • Thank you for response. The last moment stays: Spring Security Filter Chain is configured in web.xml to be called prior ServletDispatcher, that actually redirect request to wicket controller. So when I call WebApplication.get() to acquire wicket Application class inside described handler (that is part of Spr.Sec.Filter Chain), I get WicketRuntimeException"There is no application attached to current thread". Maybe you know some way around such problem? – dim1902 Oct 03 '11 at 11:45
  • Not by heart. If you're working on a separate problem, you should post another question with what you're trying to accomplish now. – millimoose Oct 03 '11 at 12:37
  • Problem is solved thanks to you advices. I just made page mounting in my WicketApplication.init() instead of trying to made the same from my handler and now all is working just fine. Thank you very much – dim1902 Oct 05 '11 at 08:03
  • @dim1902: Oh, right, that's where it was supposed to be, sorry for not making that clear. I'll edit it into the answer for clarity – millimoose Oct 05 '11 at 14:48
2

You could perform redirection by throwing a RestartResponseException.

throw new RestartResponseException(RestorePasswordPage.class, somePageParameters);

or

throw new RestartResponseException(new RestorePasswordPage(Object parameters));

RequestCycle, and other elements such as Session are automatically stored by Wicket in ThreadLocal variables, so you can get them whenever you want through static methods: RequestCycle.get()

By the way, here's a question elaborating on RestartResponseException: Wicket: how to redirect to another page?

Community
  • 1
  • 1
Xavi López
  • 27,550
  • 11
  • 97
  • 161
  • I tried to throw an exception, but it doesn't help. It triggers RestartResponseException.constructor call. But this call inside contructor: RequestCycle.get() always returns null so I get NullPointerException. Unfotunately Spring intercepts call before Wicket can do its job properly. – dim1902 Sep 30 '11 at 14:43