I have slavishly copied code from Practical Webobjects to handle just-in-time login. My code works perfectly during development (and I run through apache for this rather than direct connect) so I was surprised to see that my redirect AFTER the login page fails to redirect properly. Indeed, I return to the login page. I cannot explain this behaviour but think there must be a problem with the code executed after performing login.
Is there a better (more robust) way of generating a full URL from the fragment URI that destinationUrl contains?
Have I missed a trick within Project Wonder that handles all of this automatically?
I remember adding in the wosid in my post-login redirect as it didn't seem to be appended automatically (before I used cookies) - hence why I did this manually.
This is the superclass of any of my components that require a valid logged in user
/**
* Perform just-in-time login
*/
@Override public void appendToResponse(WOResponse response, WOContext context) {
if (isPageAccessAllowed()==false) {
WOComponent nextPage = SecureDirectAction.redirectToLoginPage(context);
nextPage.appendToResponse(response, context);
}
else {
super.appendToResponse(response, context);
}
}
And this is the superclass of any direct action classes that require a valid logged in user
/**
* Check that user is logged in prior to executing any direct actions.
*/
@Override public WOActionResults performActionNamed(String actionName) {
if (isLoggedIn()==true) {
return super.performActionNamed(actionName);
}
return redirectToLoginPage(this.context());
}
This is the code that generates a redirect to the login page. I used to generate a plain ol' WORedirect and determine a URL manually for this
as per Pract WebObjects but decided to go with ERXRedirect and its DA redirect options instead.
public static final String DESTINATION_URL = "destinationUrl";
/**
* Returns a component that redirects to a login page, remembering the current page / URL to return to!
* @param response
* @param context
* @return
*/
static public WOComponent redirectToLoginPage(WOContext context) {
try {
ERXRedirect nextPage = (ERXRedirect) Application.application().pageWithName("ERXRedirect", context);
nextPage.setDirectActionClass("DirectAction");
nextPage.setDirectActionName("login");
String uri = context.request().uri();
String encodedUrl = java.net.URLEncoder.encode(uri, "UTF-8");
NSDictionary<String, Object> destination = new NSDictionary<String, Object>(encodedUrl, DirectAction.DESTINATION_URL);
nextPage.setQueryParameters(destination);
return nextPage;
} catch (UnsupportedEncodingException e) {
throw new NSForwardException(e);
}
}
The loginAction() eventually calls this method to redirect back to the original requesting page:
/**
* Creates a redirect that will redirect to the requested landing page (destination url).
* TODO: Do we really need to add wosid here?
* @param session
* @param destinationUrl
* @return
* @throws UnsupportedEncodingException
*/
private WOComponent redirectToDestinationUrl(Session session, String destinationUrl) throws UnsupportedEncodingException {
String decodedUrl = java.net.URLDecoder.decode(destinationUrl, "UTF-8");
if (session.storesIDsInURLs()==true) {
decodedUrl = ERXWOContext.stripSessionIDFromURL(decodedUrl); // remove existing wosid, if it exists
decodedUrl = ERXExtensions.addWosidFormValue(decodedUrl, session);
}
else {
log.debug("Note: we are storing session id in cookies: therefore not using wosid...");
}
ERXRedirect redirect = (ERXRedirect) pageWithName("ERXRedirect");
// decodedUrl = "http://" + session().context().request()._serverName() + decodedUrl;
log.debug("Finally: redirecting to page: " + decodedUrl);
redirect.setUrl(decodedUrl);
return redirect;
}
I think the problem is something to do with default actions and may also be complicated by apache rewrite rules but I'm confused and as the title suggests, dimmer than a very dim thing.
All advice appreciated,
Best wishes,
Mark
--
Dr. Mark Wardle
Specialist registrar, Neurology
Cardiff, UK