Skip to content

Instantly share code, notes, and snippets.

@Tembrel
Last active September 5, 2015 14:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Tembrel/c21e3166959a68cd9048 to your computer and use it in GitHub Desktop.
Save Tembrel/c21e3166959a68cd9048 to your computer and use it in GitHub Desktop.
Revised version of default CookieAuthenticator implementation
import org.restlet.Context;
import org.restlet.Response;
import org.restlet.data.Form;
import org.restlet.data.Reference;
import org.restlet.ext.crypto.CookieAuthenticator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Implements CookieAuthenticator's challenge method.
*/
public class DefaultCookieAuthenticator extends CookieAuthenticator {
static final String LOGIN_FAILED_PARAM = "loginFailed";
public DefaultCookieAuthenticator(Context context, String realm, byte[] encryptSecretKey) {
super(context, realm, encryptSecretKey);
}
public DefaultCookieAuthenticator(Context context, boolean optional, String realm, byte[] encryptSecretKey) {
super(context, optional, realm, encryptSecretKey);
}
/**
* This should probably be the default implementation of this method in
* CookieAuthenticator.
*
* If the current resource has a redirect query value it means we're creating
* a challenge after a failed login attempt, so we try again with a query
* parameter that indicates that our last login attempt failed.
*
* Otherwise, this is a first login attempt, so we create a new reference
* to the login path with a redirect to the current resource.
*
* For example, suppose the user tries to access a guarded resource at /foo.
* Since /foo does not contain a redirect query value, the if test succeeds,
* which results in a challenge redirection to /login?targetUri=/foo.
*
* If the login attempt fails, the authentication machinery now tries to
* authenticate /login?targetUri=/foo. This time the redirect query value
* is /foo, and we redirect to /login?loginFailed=true&targetUri/foo, which
* allows the login form to let us know about the previous failure.
*
* This is somewhat brittle because other resources might use the redirect
* query name in queries, too, which would confuse this logic. That's probably
* a good reason not to use the default name, "targetUri", but at the moment
* we *are* using it.
*/
@Override public void challenge(Response response, boolean stale) {
String loginFormPath = getLoginFormPath();
if (loginFormPath == null) {
super.challenge(response, stale);
} else {
Reference ref = response.getRequest().getOriginalRef();
String redirectQueryName = getRedirectQueryName();
Form query = ref.getQueryAsForm();
String redirectQueryValue = query.getFirstValue(redirectQueryName, "");
if (redirectQueryValue.isEmpty()) {
redirectQueryValue = new Reference(loginFormPath)
.addQueryParameter(redirectQueryName, ref.toString())
.toString();
} else /* last login failed, try again */ {
redirectQueryValue = new Reference(loginFormPath)
.addQueryParameter(redirectQueryName, redirectQueryValue)
.addQueryParameter(LOGIN_FAILED_PARAM, "true")
.toString();
}
response.redirectSeeOther(redirectQueryValue);
}
}
public boolean lastLoginFailed(Form query) {
return "true".equals(query.getFirstValue(LOGIN_FAILED_PARAM, "false"));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment