There is following way to configure the authentication header in Jersey API .
//Universal builder having different credentials for different schemes
HttpAuthenticationFeature feature = HttpAuthenticationFeature.universalBuilder()
.credentialsForBasic("username1", "password1")
.credentials("username2", "password2").build();
final Client client = ClientBuilder.newClient();
client.register(feature);
But not able to figure out how to pass extra parameter to authentication header for e.g. IntegatorKey, SendBehalfOf. those are specific REST service call.
In My Case to call REST service need to pass following parameter as part of authentication header.
Username
Password
IntegatorKey
SendBehalfOf
How should I achieve this using the Jersey API ?
You didn't provide enough information in your question. It's hard guessing what you are trying to achieve. You really should consider updating your question with more details.
Having a look at the superficial information you provided, I guess you are trying to access the DocuSign REST API. If so, you could create a ClientRequestFilter, as following:
public class DocuSignAuthenticator implements ClientRequestFilter {
private String user;
private String password;
private String integatorKey;
private String sendBehalfOf;
public DocuSignAuthenticator(String username, String password,
String integatorKey, String sendBehalfOf) {
this.username = username;
this.password = password;
this.integatorKey = integatorKey;
this.sendBehalfOf = sendBehalfOf;
}
#Override
public void filter(ClientRequestContext requestContext) throws IOException {
requestContext.getHeaders().add(
"X-DocuSign-Authentication", getAuthenticationHeader());
}
private String getAuthenticationHeader() {
StringBuilder builder = new StringBuilder();
builder.append("<DocuSignCredentials>");
builder.append("<SendOnBehalfOf>");
builder.append(sendBehalfOf);
builder.append("</SendOnBehalfOf>");
builder.append("<Username>");
builder.append(username);
builder.append("</Username>");
builder.append("<Password>");
builder.append(password);
builder.append("</Password>");
builder.append("<IntegratorKey>");
builder.append(integatorKey);
builder.append("</IntegratorKey>");
builder.append("</DocuSignCredentials>");
return builder.toString();
}
}
And register it when creating a Client instance:
Client client = ClientBuilder.newClient().register(
new DocuSignAuthenticator(username, password, integatorKey, sendBehalfOf));
Related
I have an authentication resource, where I want to authenticate users, as they log in via my front-end application.
I have a facade object, which i use to authenticate the user, and create a token as such
#GET
#Path("login")
#Produces(APPLICATION_JSON)
public Response authenticateUser(#FormParam("email") String email, #FormParam("password") String password) {
try {
//skal måske ændres til bruger
User user = authenticationFacade.authenticateUser(email, password);
String token = authenticationFacade.generateAuthenticationToken(user);
return Response.ok(gson.toJson(user)).header(AUTHORIZATION, "Bearer " + token).build();
but i have a few doubts, about how to create my authentication facade, i have seen people use this convention:
#Inject
private AuthenticationFacade authenticationFacade;
and I have seen somebody, just instantiate the object:
private AuthenticationFacade authenticationFacade = new AuthenticationFacade();
In this context, what difference would it make, and what would be the best practice?
I am trying to support authenticated proxies in my Java application. My understanding that the java.net.Proxy class does not support authentication, and you need to handle authentication yourself.
I have created a subclass of the java.net.Proxy class, that takes two additional parameters, username and password.
Implementing HTTP proxy authentication was quite easy, and the method getHttpProxyAuthenticationHeader simply returns the base64 encoded auth info, to pass to HttpUrlConnection or similar.
I'm having trouble with Sock proxies though. I cannot find any documentation on sending authentication to a Socks server. I'm unsure if I need to implement the SOCKS authentication protocol in my class using a method such as authenticateSocksProxy(OutputStream stream), and then call
authedProxy.authenticateSocksProxy(outputstream);
before using the socket like
outputstream.writeBytes(myData.getBytes());
Another option would be to return a byte[] of the authentication data and then write the data manually, instead of the class writing the authentication data.
I do not think the java.net.Authenticator, or System.setProperty methods will be of any use, since my implementation needs to work on a per-connection basis and be thread-safe.
Any help is much appreciated.
Was taken from JSocks project sources:
https://code.google.com/p/jsocks-mirror/source/browse/trunk/src/java/net/sourceforge/jsocks/socks/UserPasswordAuthentication.java
I think it's clean enough to understand full process:
/**
SOCKS5 User Password authentication scheme.
*/
public class UserPasswordAuthentication implements Authentication{
/**SOCKS ID for User/Password authentication method*/
public final static int METHOD_ID = 2;
String userName, password;
byte[] request;
/**
Create an instance of UserPasswordAuthentication.
#param userName User Name to send to SOCKS server.
#param password Password to send to SOCKS server.
*/
public UserPasswordAuthentication(String userName,String password){
this.userName = userName;
this.password = password;
formRequest();
}
/** Get the user name.
#return User name.
*/
public String getUser(){
return userName;
}
/** Get password
#return Password
*/
public String getPassword(){
return password;
}
/**
Does User/Password authentication as defined in rfc1929.
#return An array containnig in, out streams, or null if authentication
fails.
*/
public Object[] doSocksAuthentication(int methodId,
java.net.Socket proxySocket)
throws java.io.IOException{
if(methodId != METHOD_ID) return null;
java.io.InputStream in = proxySocket.getInputStream();
java.io.OutputStream out = proxySocket.getOutputStream();
out.write(request);
int version = in.read();
if(version < 0) return null; //Server closed connection
int status = in.read();
if(status != 0) return null; //Server closed connection, or auth failed.
return new Object[] {in,out};
}
//Private methods
//////////////////
/** Convert UserName password in to binary form, ready to be send to server*/
private void formRequest(){
byte[] user_bytes = userName.getBytes();
byte[] password_bytes = password.getBytes();
request = new byte[3+user_bytes.length+password_bytes.length];
request[0] = (byte) 1;
request[1] = (byte) user_bytes.length;
System.arraycopy(user_bytes,0,request,2,user_bytes.length);
request[2+user_bytes.length] = (byte) password_bytes.length;
System.arraycopy(password_bytes,0,
request,3+user_bytes.length,password_bytes.length);
}
}
We are going to switch JAX-RS implementation from Jersey to Apache CXF 3.0. I just can't figure out how basic authentication is done the Apache CXF way. All examples I found where around CXF WebClient, not the JAX-RS Client API.
This is what's working with Jersey:
Client client = ClientBuilder.newClient();
client.register(HttpAuthenticationFeature.basic(config.getUsername(),config.getPassword()));
How can this be done with Apache CXF?
Create a ClientRequestFilter to perform the basic authentication:
#Provider
public class Authenticator implements ClientRequestFilter {
private String user;
private String password;
public Authenticator(String user, String password) {
this.user = user;
this.password = password;
}
#Override
public void filter(ClientRequestContext requestContext) throws IOException {
requestContext.getHeaders().add(
HttpHeaders.AUTHORIZATION, getBasicAuthentication());
}
private String getBasicAuthentication() {
String userAndPassword = this.user + ":" + this.password;
byte[] userAndPasswordBytes = userAndPassword.getBytes("UTF-8");
return "Basic " + Base64.getEncoder().encodeToString(userAndPasswordBytes);
}
}
And register it in your Client:
Client client = ClientBuilder.newClient().register(new Authenticator(user, password));
The solution above uses the Java 8 Base64.Encoder to perform the Base64 encoding.
If, for some reason, you are not using Java 8, you can use BaseEncoding from Google Guava.
I've opened an improvement in CXF Jira for this: https://issues.apache.org/jira/browse/CXF-6817
I currently have a working web app, but I need to provide means for friend website to consume my data.
There is currently JSON response in place which retrieves some data from my website to caller. It's without authentication currently and I'd like to implement some kind of per request authentication.
My web app has users which are logged in and there is a authentication in place for that. But
I have 3 requests in total for which callers can get data off of my website, what would be the simplest way to add some kind of authentication just for those 3 requests?
I'm using play framework + java
Imo the best options for this would be in the order of simplicity:
Basic authentication (since it's possible to choose either to auth once and then do session-base user recognition or authorize on every request)
2-way SSL
Combination of both
What toolkit do you use for authentication part?
I personally stuck with play-authenticate. So I might be able to answer you question in regard to this toolkit, please apply it to your particular toolkit as needed.
I will provide Basic authentication example as the easiest one. The benefit is: you could start with it and add on top it later (e.g. add Client certificate authentication via Apache later on).
So, my controller code snippet
#Restrict(value = #Group({"ROLE_WEB_SERVICE1"}), handler = BasicAuthHandler.class)
public static Result ws1() {
return TODO;
}
And the authentification handler itself
public class BasicAuthHandler extends AbstractDeadboltHandler {
public static final String HEADER_PREFIX = "Basic ";
private static final String AUTHORIZATION = "authorization";
private static final String WWW_AUTHENTICATE = "WWW-Authenticate";
#Override
public Result beforeAuthCheck(final Http.Context context) {
return basicAuthenticate(context);
}
private Result basicAuthenticate(Http.Context context) {
if (PlayAuthenticate.isLoggedIn(context.session())) {
// user is logged in
return null;
}
final String authHeader = context.request().getHeader(AUTHORIZATION);
if (authHeader == null || !authHeader.toLowerCase().startsWith(HEADER_PREFIX.toLowerCase())) {
return onAuthFailure(context, "Basic authentication header is missing");
}
final String auth = authHeader.substring(HEADER_PREFIX.length());
final byte[] decodedAuth;
final String[] credentials;
try {
decodedAuth = Base64.base64ToByteArray(auth);
credentials = new String(decodedAuth, "UTF-8").split(":");
} catch (final IOException e) {
Logger.error("basicAuthenticate", e);
return Results.internalServerError();
}
if (credentials.length != 2) {
return onAuthFailure(context, "Could not authenticate with absent password");
}
final String username = credentials[0];
final String password = credentials[1];
final AuthUser authUser = new AuthUser(password, username);
final Enum result = AuthProvider.getProvider().loginUser(authUser);
if ("USER_LOGGED_IN".equals(result.name())) {
PlayAuthenticate.storeUser(context.session(), authUser);
return null;
}
return onAuthFailure(context, "Authenticate failure");
}
#Override
public Subject getSubject(final Http.Context context) {
// your implementation
}
#Override
public Result onAuthFailure(final Http.Context context,
final String content) {
// your error hangling logic
return super.onAuthFailure(context, content);
}
}
Hopefully it fills in some blanks
I am familiar with using Jersey to create RESTful webservice servers and clients, but due to class loading issues, I am trying to convert a Jersey client into CXF. I believe I want to use an HTTP-centric client but we don't use Spring. We need to use basic HTTP authentication. The user guide has this example:
WebClient client = WebClient.create("http:books", "username", "password", "classpath:/config/https.xml");
The first parameter isn't a URI string. Is it a format used by Spring? Can this method only be used to create WebClients using Spring?
The other way of doing authentication shown is to add a header string:
String authorizationHeader = "Basic " + org.apache.cxf.common.util.Base64Utility.encode("user:password".getBytes());
webClient.header("Authorization", authorizationHeader);
I am guessing that "user:password" should be substituted with the real values, but would appreciate confirmation.
This answer came from the CXF users mailing list.
The first example referenced above had a typo in it. It has been updated to:
WebClient client = WebClient.create("http://books", "username", "password", "classpath:/config/https.xml");
The fourth argument can be null if a Spring config file is (and therefore Spring) is not being used.
So, this worked for me:
private WebClient webClient;
public RESTfulClient(String url, String username, String password)
throws IllegalArgumentException
{
this.username = username;
this.password = password;
this.serviceURL = url;
if (username == null || password == null || serviceURL == null)
{
String msg = "username, password and serviceURL MUST be defined.";
log.error(msg);
throw new IllegalArgumentException(msg);
}
webClient = WebClient.create(this.serviceURL,
this.username,
this.password,
null); // Spring config file - we don't use this
}