I have the following scenario:
Server: Jetty (with configured JAAS)
Client: Jersey invoked via JUnit (via Maven)
I have JAAS set up in the web server. I am using the client part as a test.
On the server side users are authenticated through a form with Basic authentication handled via JAAS. Obviously, users need to be authenticated before being able to view certain pages.
I would like to be able to login via the Jersey before trying to access a secured page. How can this be done? I have checked that you can define a filter, but I'm not quite sure how to use that. And -- once the user is logged in via the form, how can I proceed (from the client-side) to the page I'm actually interested in?
I would really appreciate it, if somebody could show me an example how this is done on the client side with Jersey.
I have the following JUnit test case method:
@Test
public void testLogin()
throws IOException
{
String URL_LOGIN = "http://localhost:9080/foo/auth.html";
Client client = Client.create();
String username = "me";
String password = "me";
final HTTPBasicAuthFilter authFilter = new HTTPBasicAuthFilter(username, password);
client.addFilter(authFilter);
client.addFilter(new LoggingFilter());
WebResource webResource = client.resource(URL_LOGIN);
// I even tried:
// webResource.header("Authorization", "Basic " + "base64encoded_userid:password").type("application/xml");
String page = webResource.post(String.class);
System.out.println(page);
}
Please, note:
1) http://localhost:9080/foo/auth.html is the page I am supposed to be seeing upon successful auth.
2) I am actually seeing the output of http://localhost:9080/foo/login.html.
3) Obviously, through a browser, I can successfully login via the login.html page.
What do I seem to be missing out here?
Jersey is an open source framework for developing RESTFul Web Services. It also has great inbuilt client capabilities. In this quick tutorial, we will explore the creation of JAX-RS client using Jersey 2. For a discussion on the creation of RESTful Web Services using Jersey, please refer to this article.
4 API. Packages. com.sun.jersey.api.client. Provides support for client-side communication with HTTP-based RESTful Web services.
With Basic auth you don't need to go to any login page at all. If the server is configured to use Basic auth, then you can make requests to any protected page if you include the basic auth header in your requests. The Jersey filter takes care of that. So, if Basic auth would really be what the server is using, then your code should work.
Given it does not work and the way it does not work I am pretty sure the server is configured to use form-based authentication instead of the basic authentication.
For the form-based authentication to work, you'll have to send a post request with form data including user name and password to log in and then set cookies you receive from the server to your subsequent requests (since the server - once you log in - will set the session cookie).
Look at how the login.html looks like - it should contain a form. If it is using the standard servlet form auth., the action URL of that form should be "j_security_check" and there should be two form parameters: j_username and j_password. If that is the case, you can try something like the following:
String URL_LOGIN = "http://localhost:9080/foo/j_security_check";
String URL_DATA = "http://localhost:9080/foo/auth.html";
Client client = Client.create();
// add a filter to set cookies received from the server and to check if login has been triggered
client.addFilter(new ClientFilter() {
private ArrayList<Object> cookies;
@Override
public ClientResponse handle(ClientRequest request) throws ClientHandlerException {
if (cookies != null) {
request.getHeaders().put("Cookie", cookies);
}
ClientResponse response = getNext().handle(request);
// copy cookies
if (response.getCookies() != null) {
if (cookies == null) {
cookies = new ArrayList<Object>();
}
// A simple addAll just for illustration (should probably check for duplicates and expired cookies)
cookies.addAll(response.getCookies());
}
return response;
}
});
String username = "me";
String password = "me";
// Login:
WebResource webResource = client.resource(URL_LOGIN);
com.sun.jersey.api.representation.Form form = new Form();
form.putSingle("j_username", username);
form.putSingle("j_password", password);
webResource.type("application/x-www-form-urlencoded").post(form);
// Get the protected web page:
webResource = client.resource(URL_DATA);
String response = webResource.get(String.class);
I haven't tested this, so maybe there will be some typos or bugs.
I do not use Jersey but this is not a Jersey issue per se.
First, you must be using either FORM login or BASIC authentication; unless this is a custom development I doubt you are using a 'Form with Basic Authentication'.
If you are using Basic Authentication, then things are pretty simple (though inefficient): BASIC authentication is stateless and you must send the Authorization: Basic xxxx HTTP header on EVERY request.
If you are using FORM login, things a re a bit more involved. On every request, you are supposed to send the Session Id (stored in a Cookie or using URL rewriting). If you do not send one, or if the associated session is invalidated (because it is expired for instance), the server will send a 302 (redirect) and the Login Form. You are then supposed to perform a FORM POST to the URL indicated in the form with the username and password as parameters. If authentication is successful, the server will then send the response to the original request (and a new session id). In this scenario, programmatic request must therefore be able to
Alternatively, a Jersey specific solution is available by intercepting the calls, here:
How to get jersey logs at server?
Autorization for JAAS:
String URL_DATA = "http://localhost:9080/foo/auth.html";
Client client = Client.create();
String username = "me";
String password = "me";
client.addFilter(new HTTPBasicAuthFilter(username, password));
// Get the protected web page:
WebResource webResource = client.resource(URL_DATA);
String response = webResource.get(String.class);
System.out.println(response);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With