client for secured proxy service? - axis2

I am trying to implement security to my proxy service. I have taken help for security implementation from this link:http://evanthika.blogspot.in/2012/12/pox-security-with-wso2-esb-proxy.html. My security is implemented and i can invoke it from try it as well but i want to invoke this service through a client but how to do this part i am unable to find. can anyone provide me a sample with respect to this problem? Thanks in advance

Update:
The RampartConfigBuilder class:
package org.wso2.carbon.security.ws;
import org.apache.rampart.policy.model.RampartConfig;
import org.apache.rampart.policy.model.CryptoConfig;
import java.util.Properties;
import java.io.File;
/**
* This class is used to create Rampart Configurations for different security scenarios in WSAS
*/
public class RampartConfigBuilder {
public static RampartConfig createRampartConfig(int securityScenario) {
RampartConfig rampartConfig = null;
Properties merlinProp = new Properties();
merlinProp.put("org.apache.ws.security.crypto.merlin.keystore.type", "JKS");
merlinProp.put("org.apache.ws.security.crypto.merlin.file",
"src" + File.separator + "main" + File.separator + "resources" + File.separator + "wso2carbon.jks");
merlinProp.put("org.apache.ws.security.crypto.merlin.keystore.password", "wso2carbon");
CryptoConfig sigCryptoConfig = new CryptoConfig();
sigCryptoConfig.setProvider("org.apache.ws.security.components.crypto.Merlin");
sigCryptoConfig.setProp(merlinProp);
CryptoConfig encCryptoConfig = new CryptoConfig();
encCryptoConfig.setProvider("org.apache.ws.security.components.crypto.Merlin");
encCryptoConfig.setProp(merlinProp);
switch (securityScenario) {
/**
* Scenario : Username Token
* Rampart Config : username , password callback handler
*/
case 1:
rampartConfig = new RampartConfig();
rampartConfig.setUser("admin");
rampartConfig.setPwCbClass("org.wso2.carbon.security.ws.PasswordCallbackHandler");
break;
/**
* Scenario : Non-repudiation
* Rampart Config : signatureCrypto , Password Callback Hanlder , User certificate Alias ,
* Signature CryptoConfig
*/
case 2:
rampartConfig = new RampartConfig();
rampartConfig.setUserCertAlias("wso2carbon");
rampartConfig.setPwCbClass("org.wso2.carbon.security.ws.PasswordCallbackHandler");
rampartConfig.setSigCryptoConfig(sigCryptoConfig);
break;
/**
* Scenario : Integrity
* Rampart Config : Encryption user , Signature CryptoConfig
*/
case 3:
rampartConfig = new RampartConfig();
rampartConfig.setEncryptionUser("wso2carbon");
rampartConfig.setSigCryptoConfig(sigCryptoConfig);
break;
/**
* Scenario : Confidentiality :
* Rampart Config : Encryption user , Encryption CryptoConfig
*/
case 4:
rampartConfig = new RampartConfig();
rampartConfig.setEncryptionUser("wso2carbon");
rampartConfig.setEncrCryptoConfig(encCryptoConfig);
break;
/**
* Scenario : Sign and encrypt - X509 Authentication
* Rampart Config : User cert alias , Encryption user , Sign. CryptoConfig , Enc. CryptoConfig ,
* Password Callback Handler
*/
case 5:
rampartConfig = new RampartConfig();
rampartConfig.setEncryptionUser("wso2carbon");
rampartConfig.setUserCertAlias("wso2carbon");
rampartConfig.setPwCbClass("org.wso2.carbon.security.ws.PasswordCallbackHandler");
rampartConfig.setSigCryptoConfig(sigCryptoConfig);
rampartConfig.setEncrCryptoConfig(encCryptoConfig);
break;
/**
* Scenario : Sign and Encrypt - Anonymous clients
* Rampart Config : Encryption User , Sign. CryptoConfig | Encr. CryptoConfig
*/
case 6:
rampartConfig = new RampartConfig();
rampartConfig.setEncryptionUser("wso2carbon");
rampartConfig.setEncrCryptoConfig(encCryptoConfig);
break;
/**
* Scenario : Encrypt only - Username Token Authentication
* Rampart Config : Username , PasswordCallbackHandler + Encryption User
* , Sign. CryptoConfig | Encr. CryptoConfig
*/
case 7:
rampartConfig = new RampartConfig();
rampartConfig.setUser("admin");
rampartConfig.setEncryptionUser("wso2carbon");
rampartConfig.setPwCbClass("org.wso2.carbon.security.ws.PasswordCallbackHandler");
rampartConfig.setEncrCryptoConfig(encCryptoConfig);
break;
/**
* Scenario : Sign and Encrypt - Username Token Authentication
* Rampart Config : Username + PasswordCallbackhandler , Encryption User ,
* Sign. CryptoConfig | Encr. CryptoConfig
*/
case 8:
rampartConfig = new RampartConfig();
rampartConfig.setUser("admin");
rampartConfig.setEncryptionUser("wso2carbon");
rampartConfig.setPwCbClass("org.wso2.carbon.security.ws.PasswordCallbackHandler");
rampartConfig.setEncrCryptoConfig(encCryptoConfig);
break;
/**
* Scenario : SecureConversation - Sign only - Service as STS - Bootstrap policy - Sign and Encrypt ,
* X509 Authentication
* Rampart Config : encryption user, User Cert. Alias, Password Callback Handler, Sign. CryptoConfig,
* Encr. CryptoConfig
*/
case 9:
rampartConfig = new RampartConfig();
rampartConfig.setEncryptionUser("wso2carbon");
rampartConfig.setUserCertAlias("wso2carbon");
rampartConfig.setPwCbClass("org.wso2.carbon.security.ws.PasswordCallbackHandler");
rampartConfig.setEncrCryptoConfig(encCryptoConfig);
rampartConfig.setSigCryptoConfig(sigCryptoConfig);
break;
/**
* Scenario : SecureConversation - Encrypt only - Service as STS - Bootstrap policy - Sign and Encrypt ,
* X509 Authentication Provides Confidentiality. Multiple message exchange.Clients have X509 certificates.
* Rampart Config : encryption user, User Cert. Alias, Password Callback Handler, Sign. CryptoConfig,
* Encr. CryptoConfig
*/
case 10:
rampartConfig = new RampartConfig();
rampartConfig.setEncryptionUser("wso2carbon");
rampartConfig.setUserCertAlias("wso2carbon");
rampartConfig.setPwCbClass("org.wso2.carbon.security.ws.PasswordCallbackHandler");
rampartConfig.setEncrCryptoConfig(encCryptoConfig);
rampartConfig.setSigCryptoConfig(sigCryptoConfig);
break;
/**
* Scenario : SecureConversation - Sign and Encrypt - Service as STS - Bootstrap policy - Sign and Encrypt,
* X509 Authentication
* Rampart Config : encryption user, User Cert. Alias, Password Callback Handler, Sign. CryptoConfig,
* Encr. CryptoConfig
*/
case 11:
rampartConfig = new RampartConfig();
rampartConfig.setEncryptionUser("wso2carbon");
rampartConfig.setUserCertAlias("wso2carbon");
rampartConfig.setPwCbClass("org.wso2.carbon.security.ws.PasswordCallbackHandler");
rampartConfig.setEncrCryptoConfig(encCryptoConfig);
rampartConfig.setSigCryptoConfig(sigCryptoConfig);
break;
/**
* Scenario : SecureConversation - Sign Only - Service as STS - Bootstrap policy - Sign and Encrypt ,
* Anonymous clients
* Rampart Config : Encryption User, enc. crypto config
*/
case 12:
rampartConfig = new RampartConfig();
rampartConfig.setEncryptionUser("wso2carbon");
rampartConfig.setEncrCryptoConfig(encCryptoConfig);
break;
/**
* Scenario : SecureConversation - Encrypt Only - Service as STS - Bootstrap policy - Sign and Encrypt ,
* Anonymous clients
* Rampart Config : Encryption User, enc. crypto config
*/
case 13:
rampartConfig = new RampartConfig();
rampartConfig.setEncryptionUser("wso2carbon");
rampartConfig.setEncrCryptoConfig(encCryptoConfig);
break;
/**
* Scenario : SecureConversation - Encrypt Only - Service as STS - Bootstrap policy - Sign and Encrypt ,
* Username Token Authentication
* Rampart Config : Username, encryption user, Password Callback Handler, enc. crypto config
*/
case 14:
rampartConfig = new RampartConfig();
rampartConfig.setUser("admin");
rampartConfig.setEncryptionUser("wso2carbon");
rampartConfig.setPwCbClass("org.wso2.carbon.security.ws.PasswordCallbackHandler");
rampartConfig.setEncrCryptoConfig(encCryptoConfig);
break;
/**
* Scenario : SecureConversation - Sign and Encrypt - Service as STS - Bootstrap policy - Sign and Encrypt,
* Username Token Authentication
* Rampart Config : Username, encryption user, Password Callback Handler, Encryption Crypto Config
*/
case 15:
rampartConfig = new RampartConfig();
rampartConfig.setUser("admin");
rampartConfig.setEncryptionUser("wso2carbon");
rampartConfig.setPwCbClass("org.wso2.carbon.security.ws.PasswordCallbackHandler");
rampartConfig.setEncrCryptoConfig(encCryptoConfig);
break;
}
return rampartConfig;
}
}
The PasswordCallbackHandler class:
package org.wso2.carbon.security.ws;
import org.apache.ws.security.WSPasswordCallback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;
public class PasswordCallbackHandler implements CallbackHandler{
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
WSPasswordCallback pwcb = (WSPasswordCallback)callbacks[i];
String id = pwcb.getIdentifer();
if("admin".equals(id)) {
pwcb.setPassword("admin");
} else if("wso2carbon".equals(id)) {
pwcb.setPassword("wso2carbon");
}
}
}
}
Original:
Following Java code allows you to invoke a secured service. You can invoke a service that could be secured using the 15 default security scenarios [1]. You need to change "/path/to/keystore" to point to the location of wso2carbon.jks which is shipped with wso2esb by default (ESB_HOME/repository/resources/security/wso2carbon.jks).
Also change /path/to/repo to point to client axis2 repository. The file structure is as follows.
The EPRs are hard-coded. So, you might want to change those to match with your service.
repository/
└── modules
├── addressing-1.6.1-wso2v1.mar
├── rahas-1.6.1-wso2v1.mar
└── rampart-1.6.1-wso2v1.mar
[1] http://docs.wso2.org/wiki/display/AS510/QoS+-+Security+and+Reliable+Messaging
package org.wso2.carbon.security.ws;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.axis2.description.AxisBinding;
import org.apache.axis2.description.AxisEndpoint;
import org.apache.axis2.rpc.client.RPCServiceClient;
import org.apache.neethi.Policy;
import javax.xml.namespace.QName;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Map;
public class HelloServiceClient {
static {
System.setProperty("javax.net.ssl.trustStore", "/path/to/keystore" + File.separator+ "wso2carbon.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "wso2carbon");
}
public static void main(String[] args) {
try {
int securityScenario = getSecurityScenario();
String repository = "/path/to/repo" + File.separator + "repository";
ConfigurationContext confContext =
ConfigurationContextFactory.
createConfigurationContextFromFileSystem(repository, null);
String endPoint = "HelloServiceHttpSoap12Endpoint";
if(securityScenario == 1){
endPoint = "HelloServiceHttpsSoap12Endpoint"; // scenario 1 uses HelloServiceHttpsSoap12Endpoint
}
RPCServiceClient dynamicClient =
new RPCServiceClient(confContext,
new URL("http://127.0.0.1:9763/services/HelloService?wsdl"),
new QName("http://www.wso2.org/types", "HelloService"),
endPoint);
//Engage Modules
dynamicClient.engageModule("rampart");
dynamicClient.engageModule("addressing");
//TODO : Change the port to monitor the messages through TCPMon
if(securityScenario != 1){
dynamicClient.getOptions().setTo(new EndpointReference("http://127.0.0.1:9763/services/HelloService/"));
}
//Get the policy from the binding and append the rampartconfig assertion
Map endPoints = dynamicClient.getAxisService().getEndpoints();
AxisBinding axisBinding = ((AxisEndpoint) endPoints.values().iterator().next()).getBinding();
Policy policy = axisBinding.getEffectivePolicy();
policy.addAssertion(RampartConfigBuilder.createRampartConfig(securityScenario));
axisBinding.applyPolicy(policy);
//Invoke the service
Object[] returnArray = dynamicClient.invokeBlocking(new QName("http://www.wso2.org/types","greet"),
new Object[]{"Alice"},
new Class[]{String.class});
System.out.println((String) returnArray[0]);
} catch (Exception ex) {
ex.printStackTrace();
}
}
private static int getSecurityScenario() {
int scenarioNumber = 0;
while (scenarioNumber < 1 || scenarioNumber > 15) {
System.out.print("Insert the security scenario no : ");
String inputString = readOption();
try {
scenarioNumber = new Integer(inputString);
} catch (Exception e) {
System.out.println("invalid input, insert a integer between 1 and 15");
}
if(scenarioNumber < 1 || scenarioNumber > 15){
System.out.println("Scenario number should be between 1 and 15");
}
}
return scenarioNumber;
}
private static String readOption() {
try {
BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
String str;
while ((str = console.readLine()).equals("")) {
}
return str;
} catch (Exception e) {
return null;
}
}
}

Almost all IDE's (I personnaly use WSO2 developer studio for WSO2 developments) have their ability to generate stub from WSDL file, also in ESB there is a utility (under Tool tab) generate java code from WSDL. You can choose both way to generate java code. After you generate your java stub from wsdl and invoke the Echo Service (I am saying for just in your case), you can switch the web service endpoint to proxy service url.
You can find WSO2 developer Studio, which is an Eclipse bundle, from here:
WSO2 Developer Studio
For detailed information about invoking Axis2 web service from a client you can see:
Axis2 client invocation

Related

Gmail forwards WebHook URL

I am a Java developer, how can I automatically forward the unread emails received by my personal gmail mailbox to the specified webhook URL.I tried to do this in Java but couldn't get it to work.
E.g:
public class GmailQuickstart {
/** Application name. */
private static final String APPLICATION_NAME = "Gmail API Java Quickstart";
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
/** Directory to store authorization tokens for this application. */
private static final String TOKENS_DIRECTORY_PATH = "tokens";
/**
* Global instance of the scopes required by this quickstart.
* If modifying these scopes, delete your previously saved tokens/ folder.
*/
private static final List<String> SCOPES = Collections.singletonList(GmailScopes.GMAIL_LABELS);
private static final String CREDENTIALS_FILE_PATH = "/credentials.json";
/**
* Creates an authorized Credential object.
* #param HTTP_TRANSPORT The network HTTP Transport.
* #return An authorized Credential object.
* #throws IOException If the credentials.json file cannot be found.
*/
private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
// Load client secrets.
InputStream in = GmailQuickstart.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
if (in == null) {
throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
}
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
.setAccessType("offline")
.build();
LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
Credential credential = new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
//returns an authorized Credential object.
return credential;
}
public static void main(String... args) throws IOException, GeneralSecurityException {
// Build a new authorized API client service.
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
Gmail service = new Gmail.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
.setApplicationName(APPLICATION_NAME)
.build();
// Print the labels in the user's account.
String user = "me";
ListLabelsResponse listResponse = service.users().labels().list(user).execute();
List<Label> labels = listResponse.getLabels();
if (labels.isEmpty()) {
System.out.println("No labels found.");
} else {
System.out.println("Labels:");
for (Label label : labels) {
System.out.printf("- %s\n", label.getName());
}
}
}
}
This is the official example I use. The result is a failure.
failure picture

Netty client does not send client certificate during SSL handshake that requires mutual authentication

I'm new to Netty and I try to write an echo server and client that uses mutual authentication. Unfortunately, it's not working, the client doesn't send its client certificate and the server disconnects as expected. Below an overview of what I've done so far and the client side code - that probably contains some bug or I missed something important. Thanks for going through all this!
That is what I have:
Netty version 4.1.0.CR1
Valid keystores, truststores and CRL for download on server
A complete implementation of echo server and client using JSSE directly (that is working as expected)
A working implementation of the echo server using Netty (it's working fine when used with the JSSE based client)
A client based on Netty that does not send a client certificate
Client code:
The channel handler:
package info.junius.tutorial.echo.netty.tls;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.CharsetUtil;
public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf>
{
#Override
public void channelRead0(ChannelHandlerContext ctx, ByteBuf in)
{
System.out.println("CLIENT: Received echo from server:\n" + in.toString(CharsetUtil.UTF_8));
}
#Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
{
cause.printStackTrace();
ctx.close();
}
}
The channel initialiser:
package info.junius.tutorial.echo.netty.tls;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.handler.ssl.SslContext;
public class ClientChannelInitializer extends ChannelInitializer<Channel>
{
private final SslContext context;
private final String peerHost;
private final int peerPort;
public ClientChannelInitializer(SslContext context, String peerHost, int peerPort)
{
this.context = context;
this.peerHost = peerHost;
this.peerPort = peerPort;
}
#Override
protected void initChannel(Channel channel) throws Exception
{
// Add SSL handler first to encrypt and decrypt everything.
channel.pipeline().addLast(this.context.newHandler(channel.alloc(), this.peerHost, this.peerPort));
// and then business logic.
channel.pipeline().addLast(new EchoClientHandler());
}
}
The echo client:
package info.junius.tutorial.echo.netty.tls;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
public class EchoClient
{
private final String host;
private final int port;
public EchoClient(String host, int port)
{
super();
this.host = host;
this.port = port;
}
public static void main(String[] args) throws Exception
{
if (args.length != 2)
{
System.err.println("Usage: " + EchoClient.class.getSimpleName() + " <host> <port>");
}
else
{
// Security.addProvider(new BouncyCastleProvider());
String host = args[0];
int port = Integer.parseInt(args[1]);
new EchoClient(host, port).start();
}
}
public void start() throws Exception
{
TlsContextUtil tlsContextUtil = new TlsContextUtil();
ChannelInitializer<Channel> channelInitializer = new ClientChannelInitializer(tlsContextUtil.getClientContext(), this.host, this.port);
EventLoopGroup group = new NioEventLoopGroup();
try
{
Bootstrap b = new Bootstrap();
b.group(group).channel(NioSocketChannel.class).handler(channelInitializer);
Channel channel = b.connect(this.host, this.port).sync().channel();
ChannelFuture writeFuture = channel.writeAndFlush("Hello from netty client!\n");
// channel.closeFuture().sync();
writeFuture.sync();
}
finally
{
group.shutdownGracefully().sync();
}
}
}
And a utility class that returns an SslContext:
...
public SslContext getClientContext() throws IOException
{
SslContext sslContext = null;
try
{
// truststore
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX", "SunJSSE");
tmf.init(this.getKeystore(TRUSTSTORE));
// keystore holding client certificate
KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX", "SunJSSE");
kmf.init(this.getKeystore(CLIENT_KEYSTORE), KEYSTORE_PW);
SslContextBuilder builder = SslContextBuilder.forClient().keyManager(kmf).trustManager(tmf).ciphers(PFS_CIPHERS);
// build context
sslContext = builder.build();
}
catch (NoSuchAlgorithmException
| NoSuchProviderException
| KeyStoreException
| IllegalStateException
| UnrecoverableKeyException e)
{
throw new IOException("Unable to create client TLS context", e);
}
return sslContext;
}
...
VM arguments:
-Djavax.net.debug=all -Djava.security.debug="certpath crl" -Dcom.sun.net.ssl.checkRevocation=true -Dcom.sun.security.enableCRLDP=true
I'm quite confident that my mistake must be in the Netty client code, because the system works fine when using JSSE only. Any help is highly appreciated!
Cheers,
Andy
OK, I've got it to work. It was actually my client code that was wrong (the code was based on the secure chat example that comes with Netty). So I changed it to the version used in the echo example:
EchoClientHandler:
#Override
public void channelActive(ChannelHandlerContext ctx)
{
// When notified that the channel is active send a message.
System.out.println("CLIENT: Sending request to server...");
ctx.writeAndFlush(Unpooled.copiedBuffer("Mein Schnitzel ist kaputt!\n", CharsetUtil.UTF_8));
}
and the EchoClient:
try
{
Bootstrap b = new Bootstrap();
b.group(group).channel(NioSocketChannel.class).handler(channelInitializer);
ChannelFuture f = b.connect(this.host, this.port).sync();
f.channel().closeFuture().sync();
}
finally
{
group.shutdownGracefully().sync();
}
The previous code just disconnected too early, so that the handshake never completed.

Google Glass GDK authentication using Java

I was testing the authentication for my GDK Glassware :
This is my code:
===================================================================================
import java.io.IOException;
import java.net.URISyntaxException;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.List;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.Lists;
import com.google.api.services.mirror.Mirror;
import com.google.api.services.mirror.model.Account;
import com.google.api.services.mirror.model.AuthToken;
public class InsertAccountWithJava {
/** Email of the Service Account */
private static final String SERVICE_ACCOUNT_EMAIL =
"540223414844-tj91ijj3u9**********#developer.gserviceaccount.com ";
/** Path to the Service Account's Private Key file */
private static final String SERVICE_ACCOUNT_PKCS12_FILE_PATH =
"C:/Users/Yuan/Desktop/eyenotes-847a787fecec.p12";
/** The account type, usually based on your company or app's package. */
private static final String ACCOUNT_TYPE = "com.myapplication";
/** The Mirror API scopes needed to access the API. */
private static final List<String> MIRROR_ACCOUNT_SCOPES =Arrays.asList(
"https://www.googleapis.com/auth/glass.thirdpartyauth");
public static void main(String[] args) {
try {
Mirror mirror = getMirrorService();
createAccount(mirror, "6164da1******", "zhongmeiCM", "com.myapplication", "747dab3e60dd8cd45595767580040538c8a29fcf");
} catch (GeneralSecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
/**
* Build and returns a Mirror service object authorized with the service accounts.
*
* #return Mirror service object that is ready to make requests.
*/
public static Mirror getMirrorService() throws GeneralSecurityException, IOException, URISyntaxException {
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountScopes(MIRROR_ACCOUNT_SCOPES)
.setServiceAccountPrivateKeyFromP12File(
new java.io.File(SERVICE_ACCOUNT_PKCS12_FILE_PATH))
.build();
Mirror service = new Mirror.Builder(httpTransport, jsonFactory, null)
.setHttpRequestInitializer(credential).build();
return service;
}
/**
* Creates an account and causes it to be synched up with the user's Glass.
* This example only supports one auth token; modify it if you need to add
* more than one, or to add features or user data or the password field.
*
* #param mirror the service returned by getMirrorService()
* #param userToken the user token sent to your auth callback URL
* #param accountName the account name for this particular user
* #param authTokenType the type of the auth token (chosen by you)
* #param authToken the auth token
*/
public static void createAccount(Mirror mirror, String userToken, String accountName,
String authTokenType, String authToken) {
try {
Account account = new Account();
List<AuthToken> authTokens = Lists.newArrayList();
AuthToken authToken1 = new AuthToken().setType(authTokenType).setAuthToken(authToken);
authTokens.add(authToken1);
account.setAuthTokens(authTokens);
account.setPassword("123456");
mirror.accounts().insert(
userToken, ACCOUNT_TYPE, accountName, account).execute();
} catch (IOException e) {
e.printStackTrace();
}
}
}
=====================================================================================
But I get an exception:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Invalid Value",
"reason" : "invalid"
}, {
"domain" : "global",
"message" : "Invalid Value",
"reason" : "invalid"
} ],
"message" : "Invalid Value"
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:312)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1049)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
at TestInsert.createAccount(TestInsert.java:92)
at TestInsert.main(TestInsert.java:39)
Question 1.please tell me how to generate the parameter:authToken,and what's the difference between authToken and accessToken ?
Question 2.what's the problem with my test code ? When can i get the Exception above.
authToken is an arbitrary String that you can define yourself. accessToken, on the other hand, is a token given to you during the authentication process. It is passed to the Google Mirror API to give your application access to user data.
Refer to the selected answer to this post.

How to make NTLM authentication in Apache Nutch work?

The web crawler Apache Nutch comes with a built-in support for NTLM. I'm trying to use version 1.7 to crawl a web site (Windows Sharepoint) using NTLM authentication. I have setup Nutch according to https://wiki.apache.org/nutch/HttpAuthenticationSchemes which means in particular that I have credentials
<credentials username="rickert" password="mypassword">
<authscope host="server-to-be-crawled.com" port="80" realm="CORP" scheme="NTLM"/>
</credentials>
configured. When I look at the log files I can see that Nutch tries to access the seed URL and goes through "normal" NTLM cycle: obtain an 401 error during the first GET, extract the NTLM challenge and send the NTLM authentication in the next GET (using a keep-alive connection). However, the second GET is not successful either.
That's the point when I was suspecting some fundamental problems with my credentials or the specific setup: I'm running Nutch in a Debian guest Virtual Box on a Windows host. But to my surprise both wget and curl were able to retrieve the document from within the Debian guest using my credentials. The interesting thing is that both command line tools ONLY require a username and a password to work. The full fledge NTLM specification, on the other hand, also requires a host and a domain. According to the specs the host is the one that the request originates from which I would interpret as the one that the http-agent is running on, the domain in the Windows domain that the username is associated with. My assumption is that both tools simply leave this details empty.
This is where the configuration of Nutch comes in: the host is allegedly supplied as http.agent.hostin the configuration file. The domain is supposed to be configured as the realm of the credential but the documentation rather says that this a convention and not really necessary. However, it does not matter whether I set a realm or not the result is the same. Again looking at the log file I can see some messages that the authentication is resolved using <any_realm>#server-to-be-crawled.com no matter which realm I use.
My gut feeling is that there is some wrong mapping of the Nutch configuration values onto the NTLM parameters required by the Java class httpclientthat executing the GET. I'm helpless. Can anybody give me some hints as to how to further debug this? Does anybody have a concrete config that works for a SharePoint Server? Thanks!
This is an old thread but it seems to be a common problem and I finally found a solution.
In my case the issue was that the content source that I was trying to crawl was hosted on a fairly up to date IIS server. Inspection of the headers indicated that it was using NTLMv1, but after reading that the Apache Commons HttpClient v3.x only supports NTLMv1 and not NTLMv2 I went looking for a way to add that support to nutch v1.15 without upgrading to the newer HttpComponents version of HttpClient.
The clue is in the documentation for the newer HC version of HttpClient
So, using this approach with JCIFS I managed to modify the nutch protocol-httpclient Http class so that it used my new JCIFS based NTLM scheme for authentication. Steps to do this:
Create new JCIFS based NTLMScheme
In Http.configureClient, register the use of the new scheme
Add JCIFS to the nutch protocol-httpclient plugin classpath
Job done, I was able to then crawl NTLMv2 protected websites.
By also adding lots of extra logging I could then see the authentication handshake details which showed it was in fact NTLMv2 being used.
The change in Http.configureClient looks like this:
/** Configures the HTTP client */
private void configureClient() {
LOG.info("Setting new NTLM scheme: " + JcifsNtlmScheme.class.getName());
AuthPolicy.registerAuthScheme(AuthPolicy.NTLM, JcifsNtlmScheme.class);
...
}
The new NTLM scheme implementation looks like this (needs a bit of tidying up).
public class JcifsNtlmScheme implements AuthScheme {
public static final Logger LOG = LoggerFactory.getLogger(JcifsNtlmScheme.class);
/** NTLM challenge string. */
private String ntlmchallenge = null;
private static final int UNINITIATED = 0;
private static final int INITIATED = 1;
private static final int TYPE1_MSG_GENERATED = 2;
private static final int TYPE2_MSG_RECEIVED = 3;
private static final int TYPE3_MSG_GENERATED = 4;
private static final int FAILED = Integer.MAX_VALUE;
/** Authentication process state */
private int state;
public JcifsNtlmScheme() throws AuthenticationException {
// Check if JCIFS is present. If not present, do not proceed.
try {
Class.forName("jcifs.ntlmssp.NtlmMessage", false, this.getClass().getClassLoader());
LOG.trace("jcifs.ntlmssp.NtlmMessage is present");
} catch (ClassNotFoundException e) {
throw new AuthenticationException("Unable to proceed as JCIFS library is not found.");
}
}
public String authenticate(Credentials credentials, HttpMethod method) throws AuthenticationException {
LOG.trace("authenticate called. State: " + this.state);
if (this.state == UNINITIATED) {
throw new IllegalStateException("NTLM authentication process has not been initiated");
}
NTCredentials ntcredentials = null;
try {
ntcredentials = (NTCredentials) credentials;
} catch (ClassCastException e) {
throw new InvalidCredentialsException(
"Credentials cannot be used for NTLM authentication: " + credentials.getClass().getName());
}
NTLM ntlm = new NTLM();
String charset = method.getParams().getCredentialCharset();
LOG.trace("Setting credential charset to: " + charset);
ntlm.setCredentialCharset(charset);
String response = null;
if (this.state == INITIATED || this.state == FAILED) {
LOG.trace("Generating TYPE1 message");
response = ntlm.generateType1Msg(ntcredentials.getHost(), ntcredentials.getDomain());
this.state = TYPE1_MSG_GENERATED;
} else {
LOG.trace("Generating TYPE3 message");
response = ntlm.generateType3Msg(ntcredentials.getUserName(), ntcredentials.getPassword(),
ntcredentials.getHost(), ntcredentials.getDomain(), this.ntlmchallenge);
this.state = TYPE3_MSG_GENERATED;
}
String result = "NTLM " + response;
return result;
}
public String authenticate(Credentials credentials, String method, String uri) throws AuthenticationException {
throw new RuntimeException("Not implemented as it is deprecated anyway in Httpclient 3.x");
}
public String getID() {
throw new RuntimeException("Not implemented as it is deprecated anyway in Httpclient 3.x");
}
/**
* Returns the authentication parameter with the given name, if available.
*
*
* There are no valid parameters for NTLM authentication so this method always
* returns null.
*
*
* #param name The name of the parameter to be returned
*
* #return the parameter with the given name
*/
public String getParameter(String name) {
if (name == null) {
throw new IllegalArgumentException("Parameter name may not be null");
}
return null;
}
/**
* The concept of an authentication realm is not supported by the NTLM
* authentication scheme. Always returns null.
*
* #return null
*/
public String getRealm() {
return null;
}
/**
* Returns textual designation of the NTLM authentication scheme.
*
* #return ntlm
*/
public String getSchemeName() {
return "ntlm";
}
/**
* Tests if the NTLM authentication process has been completed.
*
* #return true if Basic authorization has been processed,
* false otherwise.
*
* #since 3.0
*/
public boolean isComplete() {
boolean result = this.state == TYPE3_MSG_GENERATED || this.state == FAILED;
LOG.trace("isComplete? " + result);
return result;
}
/**
* Returns true. NTLM authentication scheme is connection based.
*
* #return true.
*
* #since 3.0
*/
public boolean isConnectionBased() {
return true;
}
/**
* Processes the NTLM challenge.
*
* #param challenge the challenge string
*
* #throws MalformedChallengeException is thrown if the authentication challenge
* is malformed
*
* #since 3.0
*/
public void processChallenge(final String challenge) throws MalformedChallengeException {
String s = AuthChallengeParser.extractScheme(challenge);
LOG.trace("processChallenge called. challenge: " + challenge + " scheme: " + s);
if (!s.equalsIgnoreCase(getSchemeName())) {
LOG.trace("Invalid scheme name in challenge. Should be: " + getSchemeName());
throw new MalformedChallengeException("Invalid NTLM challenge: " + challenge);
}
int i = challenge.indexOf(' ');
if (i != -1) {
LOG.trace("processChallenge: TYPE2 message received");
s = challenge.substring(i, challenge.length());
this.ntlmchallenge = s.trim();
this.state = TYPE2_MSG_RECEIVED;
} else {
this.ntlmchallenge = "";
if (this.state == UNINITIATED) {
this.state = INITIATED;
LOG.trace("State was UNINITIATED, switching to INITIATED");
} else {
LOG.trace("State is FAILED");
this.state = FAILED;
}
}
}
private class NTLM {
/** Character encoding */
public static final String DEFAULT_CHARSET = "ASCII";
/**
* The character was used by 3.x's NTLM to encode the username and password.
* Apparently, this is not needed in when passing username, password from
* NTCredentials to the JCIFS library
*/
private String credentialCharset = DEFAULT_CHARSET;
void setCredentialCharset(String credentialCharset) {
this.credentialCharset = credentialCharset;
}
private String generateType1Msg(String host, String domain) {
jcifs.ntlmssp.Type1Message t1m = new jcifs.ntlmssp.Type1Message(
jcifs.ntlmssp.Type1Message.getDefaultFlags(), domain, host);
String result = jcifs.util.Base64.encode(t1m.toByteArray());
LOG.trace("generateType1Msg: " + result);
return result;
}
private String generateType3Msg(String username, String password, String host, String domain,
String challenge) {
jcifs.ntlmssp.Type2Message t2m;
try {
t2m = new jcifs.ntlmssp.Type2Message(jcifs.util.Base64.decode(challenge));
} catch (IOException e) {
throw new RuntimeException("Invalid Type2 message", e);
}
jcifs.ntlmssp.Type3Message t3m = new jcifs.ntlmssp.Type3Message(t2m, password, domain, username, host, 0);
String result = jcifs.util.Base64.encode(t3m.toByteArray());
LOG.trace("generateType3Msg username: [" + username + "] host: [" + host + "] domain: [" + domain
+ "] response: [" + result + "]");
return result;
}
}
}

Difference between KeyStore and KeyManager/TrustManager

What is the difference between using a KeyStore Object for the keystore and truststore; as opposed to using the KeyManager and TrustManager?
Let me explain why I am asking. I am working with RESTEasy and needed to make a REST call over HTTPS with SSL certificates. I needed to augment how RESTEasy created the ClientRequest. Here is what I figured out initially:
public void afterPropertiesSet() throws Exception {
Assert.isTrue(StringUtils.isNotBlank(getKeystoreName()), "Key Store Name is Blank");
Assert.isTrue(StringUtils.isNotBlank(getKeystorePassword()), "Key Store Password is Blank.");
Assert.isTrue(StringUtils.isNotBlank(getKeystorePath()), "Key Store Path is Blank");
Assert.isTrue(StringUtils.isNotBlank(getTruststoreName()), "Trust Store Name is Blank");
Assert.isTrue(StringUtils.isNotBlank(getTruststorePassword()), "Trust Store Password is Blank.");
Assert.isTrue(StringUtils.isNotBlank(getTruststorePath()), "Trust Store Path is Blank");
// Set the keystore and truststore for mutual authentication
createKeystore();
createTruststore();
if (getHttpClient() == null) {
// Initialize HTTP Client
initializeHttpClient();
}
Assert.notNull(getHttpClient(), "HTTP Client is NULL after initialization");
}
public ClientRequest createClientRequest(String uri) throws URISyntaxException {
ClientExecutor clientExecutor = new ApacheHttpClient4Executor(getHttpClient());
ClientRequestFactory fac = new ClientRequestFactory(clientExecutor, new URI(uri));
return fac.createRequest(uri);
}
private void createTruststore() throws KeyStoreException, FileNotFoundException, IOException,
NoSuchAlgorithmException, CertificateException {
String truststoreFilePath = getTruststorePath() + getTruststoreName();
KeyStore truststore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream truststoreInput = getClass().getClassLoader().getResourceAsStream(truststoreFilePath);
truststore.load(truststoreInput, getTruststorePassword().toCharArray());
}
private void createKeystore() throws KeyStoreException, FileNotFoundException, IOException,
NoSuchAlgorithmException, CertificateException {
String keystoreFilePath = getKeystorePath() + getKeystoreName();
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream keystoreInput = getClass().getClassLoader().getResourceAsStream(keystoreFilePath);
keystore.load(keystoreInput, getKeystorePassword().toCharArray());
}
/**
* Initializes the HTTP Client
*
* #throws KeyStoreException
* #throws NoSuchAlgorithmException
* #throws UnrecoverableKeyException
* #throws KeyManagementException
*/
private void initializeHttpClient() throws KeyManagementException, UnrecoverableKeyException,
NoSuchAlgorithmException, KeyStoreException {
// Register https and http with scheme registry
SchemeRegistry schemeRegistry = new SchemeRegistry();
SSLSocketFactory sslSocketFactory = new SSLSocketFactory(getKeystore(), getKeystorePassword(), getTrustStore());
schemeRegistry.register(new Scheme(HTTP, 80, PlainSocketFactory.getSocketFactory()));
schemeRegistry.register(new Scheme(HTTPS, 443, sslSocketFactory));
// Set connection params
HttpConnectionParams.setConnectionTimeout(httpParameters, serviceConnectionTimeout);
HttpConnectionParams.setSoTimeout(httpParameters, readTimeout);
HttpConnectionParams.setStaleCheckingEnabled(httpParameters, true);
// Create Connection Manager
PoolingClientConnectionManager clientManager = new PoolingClientConnectionManager(schemeRegistry);
clientManager.setMaxTotal(maxTotalConnections);
clientManager.setDefaultMaxPerRoute(defaultMaxConnectionsPerHost);
httpClient = new DefaultHttpClient(clientManager, httpParameters);
}
I ran into a problem with the Peer Certificates and kept getting an exception:
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
I then searched around and found articles/blogs about setting up the HttpClient but using TrustManager and KeyManager. I refactored the code to do the following:
public void afterPropertiesSet() throws Exception {
Assert.isTrue(StringUtils.isNotBlank(getKeystoreName()), "Key Store Name is Blank");
Assert.isTrue(StringUtils.isNotBlank(getKeystorePassword()), "Key Store Password is Blank.");
Assert.isTrue(StringUtils.isNotBlank(getKeystorePath()), "Key Store Path is Blank");
Assert.isTrue(StringUtils.isNotBlank(getTruststoreName()), "Trust Store Name is Blank");
Assert.isTrue(StringUtils.isNotBlank(getTruststorePassword()), "Trust Store Password is Blank.");
Assert.isTrue(StringUtils.isNotBlank(getTruststorePath()), "Trust Store Path is Blank");
if (getHttpClient() == null) {
// Initialize HTTP Client
initializeHttpClient();
}
Assert.notNull(getHttpClient(), "HTTP Client is NULL after initialization");
}
public ClientRequest createClientRequest(String uri) throws URISyntaxException {
ClientExecutor clientExecutor = new ApacheHttpClient4Executor(getHttpClient());
ClientRequestFactory fac = new ClientRequestFactory(clientExecutor, new URI(uri));
return fac.createRequest(uri);
}
/**
* Initializes the HTTP Client
*
* #throws KeyStoreException
* #throws NoSuchAlgorithmException
* #throws UnrecoverableKeyException
* #throws KeyManagementException
*/
private void initializeHttpClient() throws Exception {
if (isCheckPeerCertificates()) {
checkPeerCerts();
}
// Create Trust and Key Managers
// Use TrustManager and KeyManager instead of KeyStore
TrustManager[] trustManagers = getTrustManagers(getTruststorePassword());
KeyManager[] keyManagers = getKeyManagers(getKeystorePassword());
// Create SSL Context
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(keyManagers, trustManagers, new SecureRandom());
// Create SSL Factory
SSLSocketFactory sslSocketFactory = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
// Register https and http with scheme registry
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme(HTTP, 80, PlainSocketFactory.getSocketFactory()));
schemeRegistry.register(new Scheme(HTTPS, 443, sslSocketFactory));
// Set connection params
HttpConnectionParams.setConnectionTimeout(httpParameters, serviceConnectionTimeout);
HttpConnectionParams.setSoTimeout(httpParameters, readTimeout);
HttpConnectionParams.setStaleCheckingEnabled(httpParameters, true);
// Create Connection Manager
PoolingClientConnectionManager clientManager = new PoolingClientConnectionManager(schemeRegistry);
clientManager.setMaxTotal(maxTotalConnections);
clientManager.setDefaultMaxPerRoute(defaultMaxConnectionsPerHost);
httpClient = new DefaultHttpClient(clientManager, httpParameters);
}
private TrustManager[] getTrustManagers(String trustStorePassword) throws Exception {
String truststoreFilePath = getTruststorePath() + getTruststoreName();
InputStream trustStoreInput = getClass().getClassLoader().getResourceAsStream(truststoreFilePath);
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(trustStoreInput, trustStorePassword.toCharArray());
TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmfactory.init(trustStore);
return tmfactory.getTrustManagers();
}
private KeyManager[] getKeyManagers(String keyStorePassword) throws Exception {
String keystoreFilePath = getKeystorePath() + getKeystoreName();
InputStream keyStoreInput = getClass().getClassLoader().getResourceAsStream(keystoreFilePath);
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(keyStoreInput, keyStorePassword.toCharArray());
KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmfactory.init(keyStore, keyStorePassword.toCharArray());
return kmfactory.getKeyManagers();
}
The second code works just fine. So, what is the a difference between the 2 types of usages?
I think this can help you:
Difference between trustStore and keyStore in Java - SSL
First and major difference between trustStore and keyStore is that trustStore is used by TrustManager and keyStore is used by KeyManager class in Java. KeyManager and TrustManager performs different job in Java, TrustManager determines whether remote connection should be trusted or not i.e. whether remote party is who it claims to and KeyManager decides which authentication credentials should be sent to the remote host for authentication during SSL handshake. if you are an SSL Server you will use private key during key exchange algorithm and send certificates corresponding to your public keys to client, this certificate is acquired from keyStore. On SSL client side, if its written in Java, it will use certificates stored in trustStore to verify identity of Server.
Read more: JavaRevisited blog: http://javarevisited.blogspot.com/2012/09/difference-between-truststore-vs-keyStore-Java-SSL.html (Archived here.)