In Restlet 2.3 I am using a ChallengeAuthenticator
with ChallengeScheme.HTTP_BASIC
to protect application resources. When the server receives an incorrect set of credentials the server correctly returns a 401 Unauthorized
response. Also correctly it adds the following header:
WWW-Authenticate → Basic realm="My security Realm"
The problem is when that response goes back to a browser rather than a server (as is the case with the AngularJS application GUI), the browser natively interprets that 401
response and launches an 'Authentication Required' modal.
What I would like to try and achieve is to read the request headers (easily done) and if the X-Requested-With: XMLHttpRequest
header is present I would like to suppress the WWW-Authenticate
header in the '401' response.
Currently the WWW-Authenticate
header is automatically set so my question is how can I override this default header being set and handle it manually?
In your case, you should use a filter to remove the header WWW-Authenticate
from the response. This header corresponds to a challenge request in the response.
Here is the content of the filter:
public class SecurityPostProcessingFilter extends Filter {
public SecurityPostProcessingFilter(
Context context, Restlet next) {
super(context, next);
}
@Override
protected void afterHandle(Request request, Response response) {
String requestedWith
= request.getHeaders().getFirstValue("X-Requested-With");
if ("XMLHttpRequest".equals(requestedWith)) {
response.getChallengeRequests().clear();
}
}
}
You need to add it within the createInboundRoot
method of your Restlet application, as described below
public class RestletApplication extends Application {
(...)
@Override
public Restlet createInboundRoot() {
Router router = new Router(getContext());
(...)
ChallengeAuthenticator guard = new ChallengeAuthenticator(
null, ChallengeScheme.HTTP_BASIC, "testRealm");
(...)
guard.setNext(router);
Filter filter = new SecurityPostProcessingFilter(
getContext(), guard);
return filter;
}
}
This will remove the header WWW-Authenticate
from the response when the value of the header X-Requested-From
is equals to XMLHttpRequest
in the request.
FYI, there is a page on the Restlet web site that describes the mapping between HTTP headers and the Restlet API: http://restlet.com/technical-resources/restlet-framework/guide/2.2/core/http-headers-mapping.
Hope it helps you, Thierry