|
import org.restlet.Context; |
|
import org.restlet.Response; |
|
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 { |
|
|
|
final static Logger logger = LoggerFactory.getLogger(DefaultCookieAuthenticator.class); |
|
|
|
|
|
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 use it directly, |
|
* because it means we're creating a challenge after a failed login attempt, |
|
* so by using the redirect query value, we're restarting the whole process. |
|
* 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, the if clause will be skipped, and the redirection will be to |
|
* /foo, i.e., back to our starting point to begin the process anew. |
|
* |
|
* 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(); |
|
String redirectQueryValue = ref.getQueryAsForm().getFirstValue( |
|
redirectQueryName, ""); |
|
|
|
if (redirectQueryValue.isEmpty()) { |
|
redirectQueryValue = new Reference(loginFormPath) |
|
.addQueryParameter(redirectQueryName, ref.toString()) |
|
.toString(); |
|
} |
|
|
|
response.redirectSeeOther(redirectQueryValue); |
|
} |
|
} |
|
} |