How to explicitly point my service account file in code - java

In other Google Services such as Storage, BigQuery you can define what service account you are going to use in the JAVA code:
// You can specify a credential file by providing a path to GoogleCredentials.
// Otherwise credentials are read from the GOOGLE_APPLICATION_CREDENTIALS environment variable.
GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(jsonPath))
.createScoped(Lists.newArrayList("https://www.googleapis.com/auth/cloud-platform"));
Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();
Using Google Secret Manager it seems not possibile. Why?
The only way is to set an environment variable on VM?
I tried as suggested to use Credentials Provider
GoogleCredentials credentials = ServiceAccountCredentials.fromStream(credentialsInputStream);
CredentialsProvider credentialsProvider = FixedCredentialsProvider.create(credentials);
SecretManagerServiceSettings settings = SecretManagerServiceSettings.newBuilder().setCredentialsProvider(credentialsProvider).build();
client = SecretManagerServiceClient.create(settings);
but it doesn't work
Caused by: java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;CLjava/lang/Object;)V
at io.grpc.Metadata$Key.validateName(Metadata.java:742)
at io.grpc.Metadata$Key.<init>(Metadata.java:750)
at io.grpc.Metadata$Key.<init>(Metadata.java:668)
at io.grpc.Metadata$AsciiKey.<init>(Metadata.java:959)
at io.grpc.Metadata$AsciiKey.<init>(Metadata.java:954)
at io.grpc.Metadata$Key.of(Metadata.java:705)
at io.grpc.Metadata$Key.of(Metadata.java:701)
at com.google.api.gax.grpc.GrpcHeaderInterceptor.<init>(GrpcHeaderInterceptor.java:60)
at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.createSingleChannel(InstantiatingGrpcChannelProvider.java:239)
at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.access$1600(InstantiatingGrpcChannelProvider.java:71)
at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider$1.createSingleChannel(InstantiatingGrpcChannelProvider.java:210)
at com.google.api.gax.grpc.ChannelPool.create(ChannelPool.java:72)
at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.createChannel(InstantiatingGrpcChannelProvider.java:217)
at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.getTransportChannel(InstantiatingGrpcChannelProvider.java:200)
at com.google.api.gax.rpc.ClientContext.create(ClientContext.java:156)
at com.google.cloud.secretmanager.v1.stub.GrpcSecretManagerServiceStub.create(GrpcSecretManagerServiceStub.java:237)
at com.google.cloud.secretmanager.v1.stub.SecretManagerServiceStubSettings.createStub(SecretManagerServiceStubSettings.java:226)
at com.google.cloud.secretmanager.v1.SecretManagerServiceClient.<init>(SecretManagerServiceClient.java:154)
at com.google.cloud.secretmanager.v1.SecretManagerServiceClient.create(SecretManagerServiceClient.java:135)
because of an Exception in the class com.google.cloud.secretmanager.v1.SecretManagerServiceClient
/**
* Constructs an instance of SecretManagerServiceClient, using the given settings. This is
* protected so that it is easy to make a subclass, but otherwise, the static factory methods
* should be preferred.
*/
protected SecretManagerServiceClient(SecretManagerServiceSettings settings) throws IOException {
this.settings = settings;
this.stub = ((SecretManagerServiceStubSettings) settings.getStubSettings()).createStub();
}

To customize credentials, you can create a custom secretManagerServiceSettings:
SecretManagerServiceSettings secretManagerServiceSettings =
SecretManagerServiceSettings.newBuilder()
.setCredentialsProvider(FixedCredentialsProvider.create(credentials))
.build();
SecretManagerServiceClient client =
SecretManagerServiceClient.create(secretManagerServiceSettings);

Related

Google API authentication in Java without using environment variable

I have set up a simple test app to interact with Google's Natural Language API. I created a service account, and downloaded the JSON credentials. I am running on a local development machine, so I set the GOOGLE_APPLICATION_CREDENTIALS environment variable to point to the JSON file. To be clear, this works: the app successfully makes some API calls and displays the results.
I would like to remove the dependence on the environment variable. How can I use the known location of the JSON file (or any other approach) in the application to create the LanguageServiceClient with those credentials?
You can register is like this:
DatastoreOptions options = DatastoreOptions.newBuilder()
.setProjectId(PROJECT_ID)
.setAuthCredentials(AuthCredentials.createForJson(
new FileInputStream(PATH_TO_JSON_KEY))).build();
Does that help?
You can always pass the full json file as String as follows:
CredentialsProvider credentialsProvider;
String credentials = "[YOUR JSON FILE CONTENT]";
try {
credentialsProvider
= FixedCredentialsProvider.create(
ServiceAccountCredentials.fromStream(new ByteArrayInputStream(credentials.getBytes())));
} catch (IOException ex) {
Logger.getLogger(GoogleNLPService.class.getName()).log(Level.SEVERE, null, ex);
}
LanguageServiceSettings.Builder languageServiceSettingsBuilder
= LanguageServiceSettings.newBuilder();
LanguageServiceSettings languageServiceSettings = languageServiceSettingsBuilder.setCredentialsProvider(credentialsProvider).build();
List<NamedEntity> entities = new ArrayList<>();
try (LanguageServiceClient language = LanguageServiceClient.create(languageServiceSettings)) {
...
}
Alternatively, you can place your json file in resources folder and then read it as:
credentialsProvider
= FixedCredentialsProvider.create(
ServiceAccountCredentials.fromStream(new FileInputStream("./src/main/resources/FILENAME.json")));
However, this relative path didn't work when I uploaded my app in Heroku. So, I have decided to use the String solution.
We use a service account + GoogleCredential.Builder -- (note that this example uses a credential file in p12 format); example follows:
private GoogleCredential authorize() throws IOException, GeneralSecurityException
{
return new GoogleCredential.Builder()
.setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(serviceAccount)
.setServiceAccountScopes(SCOPES)
.setServiceAccountUser(serviceAccountUser)
// variable p12File is a String w/ path to the .p12 file name
.setServiceAccountPrivateKeyFromP12File(new java.io.File(p12File))
.build();
}
Following the advice from tokyohans answer above, I can confirm this works for LanguageServiceClient:
// old-school Google Authentication
GoogleCredential credential = null;
credential = GoogleCredential.fromStream(new FileInputStream("google.json"));
Collection<String> scopes = Collections.singleton("https://www.googleapis.com/auth/cloud-language");
if (credential.createScopedRequired()) {
credential = credential.createScoped(scopes);
}
// copy over key values, note the additional "s", set some expiry
// com.google.auth.oauth2.GoogleCredentials
GoogleCredentials sac = ServiceAccountCredentials.newBuilder()
.setPrivateKey(credential.getServiceAccountPrivateKey())
.setPrivateKeyId(credential.getServiceAccountPrivateKeyId())
.setClientEmail(credential.getServiceAccountId())
.setScopes(scopes)
.setAccessToken(new AccessToken(credential.getAccessToken(), new LocalDate().plusYears(1).toDate()))
.build();
// Latest generation Google libs, GoogleCredentials extends Credentials
CredentialsProvider cp = FixedCredentialsProvider.create(sac);
LanguageServiceSettings settings = (LanguageServiceSettings) LanguageServiceSettings.newBuilder().setCredentialsProvider(cp).build();
return LanguageServiceClient.create(settings);
This looks like an older thread but sharing our findings for what it's worth.
This example is for the Google ImageAnnotatorClient, but I am pretty sure it is very similar for LanguageServiceClient.
Old-school google libraries (P12 file era) use GoogleCredential vs. the new GoogleCredentials. They look very similar. Digging into the Type hierarchy I found a FixedCredentialsProvider which seems to do the trick.
This worked for us, we got the Google Vision API up and running with an existing P12 file without environment variable. It does look like Google wants us to migrate away from this so not recommending this approach long-term.
// old-school Google Authentication
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
// Spring code
String pemFile = "yourPemFile.p12";
Resource r = new ClassPathResource(pemFile);
String serviceAccountEmail = "xxxx#xxxx.iam.gserviceaccount.com";
// com.google.api.client.googleapis.auth.oauth2.GoogleCredential.Builder
Builder credentialBuilder = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(serviceAccountEmail)
.setServiceAccountPrivateKeyFromP12File(r.getFile());
// Cloud API endpoints, make sure that the API is enabled
Collection<String> scopes = Collections.singleton("https://www.googleapis.com/auth/cloud-vision");
GoogleCredential credential = credentialBuilder
.setServiceAccountScopes(scopes).build();
// copy over key values, note the additional "s", set some expiry
// com.google.auth.oauth2.GoogleCredentials
GoogleCredentials sac = ServiceAccountCredentials.newBuilder()
.setPrivateKey(gc.getServiceAccountPrivateKey())
.setPrivateKeyId(gc.getServiceAccountPrivateKeyId())
.setClientEmail(gc.getServiceAccountId())
.setScopes(scopes)
.setAccessToken(new AccessToken(gc.getAccessToken(), new LocalDate().plusYears(1).toDate()))
.build();
// Latest generation Google libs, GoogleCredentials extends Credentials
CredentialsProvider cp = FixedCredentialsProvider.create(sac);
ImageAnnotatorSettings settings = ImageAnnotatorSettings.newBuilder().setCredentialsProvider(cp).build();
ImageAnnotatorClient googleApi = ImageAnnotatorClient.create(settings);

azure java sdk authentication

I would like to list available IP VM's in the new Azure portal using Java SDK.
Couple of years back in the good old classic portal, I had followed the usual management certificate procedure to access vm's,create vm's and work with Azure Endpoints.
Fast fwd now I see that they have used a new portal and new mechanisms to interact with Java SDK. I read somewhere in the above link that with the old way with certificates, I can manage only the class portal resources.
I'm trying to code a simple program which authenticates and lists the vm's of the new portal as a start. Seems like they have complicated it a lot.
I followed the below link to "Create service principal with password"
https://azure.microsoft.com/en-us/documentation/articles/resource-group-authenticate-service-principal/
Then I went to this link
https://azure.microsoft.com/en-us/documentation/samples/resources-java-manage-resource-group/
which asked me go the "See how to create an Auth file" link in above page
(mine is not a webapp and when I try to create the AD as a native client application, it is not allowing me to save keys in configure tab, so I had to create a web app)
After doing all this, I got stuck with this below error
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
'authority' Uri should have at least one segment in the path (i.e.https://<host>/<path>/...)
java.lang.IllegalArgumentException: 'authority' Uri should have at least one segment in the path (i.e. https://<host>/<path>/...)
at com.microsoft.aad.adal4j.AuthenticationAuthority.detectAuthorityType(AuthenticationAuthority.java:190)
at com.microsoft.aad.adal4j.AuthenticationAuthority.<init>(AuthenticationAuthority.java:73)
When I checked it says that the error is because I don't have a valid client application id in your Azure Active Directory.
Is there any simple way to authenticate and start using the API's?
#Vikram, I suggest that you can try to refer to the article to create an application on AAD.
Then you can follow the code below to get the access token for authentication.
// The parameters include clientId, clientSecret, tenantId, subscriptionId and resourceGroupName.
private static final String clientId = "<client-id>";
private static final String clientSecret = "<key>";
private static final String tenantId = "<tenant-id>";
private static final String subscriptionId = "<subscription-id>";
// The function for getting the access token via Class AuthenticationResult
private static AuthenticationResult getAccessTokenFromServicePrincipalCredentials()
throws ServiceUnavailableException, MalformedURLException, ExecutionException, InterruptedException {
AuthenticationContext context;
AuthenticationResult result = null;
ExecutorService service = null;
try {
service = Executors.newFixedThreadPool(1);
// TODO: add your tenant id
context = new AuthenticationContext("https://login.microsoftonline.com/" + tenantId, false, service);
// TODO: add your client id and client secret
ClientCredential cred = new ClientCredential(clientId, clientSecret);
Future<AuthenticationResult> future = context.acquireToken("https://management.azure.com/", cred, null);
result = future.get();
} finally {
service.shutdown();
}
if (result == null) {
throw new ServiceUnavailableException("authentication result was null");
}
return result;
}
String accessToken = getAccessTokenFromServicePrincipalCredentials().getAccessToken();
If you want to list the VMs on new portal, you can try to use the REST API List the resources in a subscription to get all resources and filter the VMs via the resource type Microsoft.Compute/virtualMachines.
Hope it helps.

Java Service Bus Shared Access Token

Configuration config =
ServiceBusConfiguration.configureWithSASAuthentication(
URL,
"RootManageSharedAccessKey",
token,
".servicebus.windows.net"
);
This is the code for configuration for java service bus implementation. I am interested in passing a shared access signature not a shared access key. I am not sure if this implementation for the java azure sdk supports this. How exactly would I do this. I keep getting a 401-unauthorized error when I use the shared access signature token in the token variable. Any ideas?
According to the source code of Azure Service Bus SDK for Java, the four arguments for the function configureWithSASAuthentication should be the namespace, sasKeyName, sasKey & serviceBusRootUri(default pass ".servicebus.windows.net").
The namespace, sasKeyName & sasKey you can find them via click the CONNECTION INFORMATION button at the bottom of your service bus, please see the figures below.
Fig 1. The CONNECTION INFORMATION button at the bottom of the service bus page
Fig 2. Copy the CONNECTION STRING and extract the namespace, sasKeyName & sasKey
For example, the connection string is Endpoint=sb://abc-ns.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=ABCdefg123!##=, then the namespace, sasKeyName, sasKey are separately abc-ns, RootManageSharedAccessKey, ABCdefg123!##=.
So the code should be as below.
Configuration config =
ServiceBusConfiguration.configureWithSASAuthentication(
"abc-ns",
"RootManageSharedAccessKey",
"ABCdefg123!##=",
".servicebus.windows.net"
);
And you can also find them at the CONFIGURE tab of your service bus page, please see the figure below.
Fig 3. The CONFIGURE tab
I can see that you created a Configuration object here. Normally we use it to creat a topic in Java, eg:
Configuration config =
ServiceBusConfiguration.configureWithSASAuthentication(
"namespace",
"sasKeyName",
"sasKey",
"serviceBusRootUri"
);
ServiceBusContract service = ServiceBusService.create(config);
TopicInfo topicInfo = new TopicInfo("TestTopic");
CreateTopicResult result = service.createTopic(topicInfo);
or to create a queue, eg:
Configuration config =
ServiceBusConfiguration.configureWithSASAuthentication(
"namespace",
"sasKeyName",
"sasKey",
"serviceBusRootUri"
);
ServiceBusContract service = ServiceBusService.create(config);
QueueInfo queueInfo = new QueueInfo("TestQueue");
CreateQueueResult result = service.createQueue(queueInfo);
and also we can create them by shared access signature:
create a topic(c#)
Uri uri = ServiceBusEnvironment.CreateServiceUri("sb", "namespace", string.Empty);
string name = "sasKeyName";
string key = "sasKey";
TokenProvider tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(name, key);
NamespaceManager namespaceManager = new NamespaceManager(uri, tokenProvider);
namespaceManager.CreateTopic("DataCollectionTopic");
create a queue(c#):
Uri uri = ServiceBusEnvironment.CreateServiceUri("sb",
"namespace", string.Empty);
string name = "sasKeyName";
string key = "sasKey";
TokenProvider tokenProvider =
TokenProvider.CreateSharedAccessSignatureTokenProvider(name, key);
NamespaceManager namespaceManager =
new NamespaceManager(uri, tokenProvider);
namespaceManager.CreateQueue("DataCollectionQueue");
The namespace, sasKeyName, sasKey are configured in portal just as what Perter showed.

How do I access a Google Spreadsheet from App Engine using a Service Account?

I have an application on Google App Engine (hosted on appspot.com) which is going to be used by a few users to grab some stuff off the internet, save it in the Datastore and then write it to a Google Spreadsheet. I'm looking to use a Service Account to access the spreadsheet but I run into a 400 OK { "error" : "invalid_grant" } problem when I try to do anything, regardless of whether I try to create a file using the Drive API or access an existing file using Spreadsheets API.
I've turned on both Drive API and Drive SDK in the APIs Console and generated a P12 key. This is my method for building a GoogleCredential:
private GoogleCredential getGoogleCredential() throws IOException, GeneralSecurityException {
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(TRANSPORT)
.setJsonFactory(FACTORY)
.setServiceAccountId("1511XXX90247.apps.googleusercontent.com")
.setServiceAccountScopes(scopes)
.setServiceAccountPrivateKeyFromP12File(
new File("05a605b0fXXXd2a6be864be15d81a2bd629d3bd6-privatekey.p12"))
.setServiceAccountUser("XXX#gmail.com") // My personal e-mail address which I used to create the project
.build();
return credential;
}
The ServiceAccountID comes from the APIs Console. I've tried using 1511XXX90247#developer.gserviceaccount.com as my ServiceAccountUser as well as myappname#appspot.gserviceaccount.com. The scopes I'm using are as follows:
https://spreadsheets.google.com/feeds
https://docs.google.com/feeds
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/drive.file
Here is the code that fails when I try to use Spreadsheets API:
SpreadsheetService service = new SpreadsheetService("name of my app");
service.setOAuth2Credentials(getGoogleCredential());
FeedURLFactory factory = FeedURLFactory.getDefault();
SpreadsheetQuery query = new SpreadsheetQuery(factory.getSpreadsheetsFeedUrl());
query.setTitleQuery("test");
SpreadsheetFeed feed = service.query(query, SpreadsheetFeed.class);
The code fails when the service tries execute the query.
Here's the Drive code I tried that also fails:
Drive drive = new Drive.Builder(TRANSPORT, FACTORY,
getGoogleCredential()).build();
com.google.api.services.drive.model.File file = new com.google.api.services.drive.model.File();
file.setTitle("test");
file.setMimeType("application/vnd.google-apps.spreadsheet");
drive.files().insert(file).execute(); // This is where the code fails
No matter what I try, I always seem to end up with the same ìnvalid grant` error. Here's a partial stacktrace:
com.google.gdata.util.AuthenticationException: Failed to refresh access token: 400 OK { "error" : "invalid_grant" }
at com.google.gdata.client.GoogleAuthTokenFactory$OAuth2Token.refreshToken(GoogleAuthTokenFactory.java:260)
at com.google.gdata.client.GoogleAuthTokenFactory.handleSessionExpiredException(GoogleAuthTokenFactory.java:702)
at com.google.gdata.client.GoogleService.handleSessionExpiredException(GoogleService.java:738) at com.google.gdata.client.GoogleService.getFeed(GoogleService.java:680)
at com.google.gdata.client.Service.query(Service.java:1237)
at com.google.gdata.client.Service.query(Service.java:1178)
at spam.gwt.scraper.server.spreadsheets.APIConnector.doGet(APIConnector.java:66)
I've tried to look for answers everywhere, including but not limited to the Google Developers Spreadsheets Guide, this Service Account-related Stack Overflow question and this Google App Engine-specific Stack Overflow question. What with the developments (eg. Docs -> Drive) it's hard to find up-to-date info, never mind info that pertains specifically to GAE.
I use the builtin Service Account of the App Engine application rather than creating my own; this way the private key is save (not stored locally, only on app engine).
For Drive:
protected Drive createDriveService() throws BookingSheetException {
HttpTransport httpTransport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
GoogleClientRequestInitializer keyInitializer =
new CommonGoogleClientRequestInitializer(API_KEY);
AppIdentityCredential credential =
new AppIdentityCredential.Builder(Arrays.asList(DriveScopes.DRIVE)).build();
Drive service = new Drive.Builder(httpTransport, jsonFactory, null)
.setHttpRequestInitializer(credential)
.setGoogleClientRequestInitializer(keyInitializer)
.setApplicationName(appname).build();
return service;
}
For Spreadsheet:
private Credential creds;
/**
* Keep the expiration time of the access token to renew it before expiry
*/
private Calendar expirationTime = Calendar.getInstance();
protected void initCredentials() {
List<String> scopes = Arrays.asList("https://spreadsheets.google.com/feeds");
AppIdentityService appIdentity = AppIdentityServiceFactory.getAppIdentityService();
AppIdentityService.GetAccessTokenResult accessToken = appIdentity.getAccessToken(scopes);
expirationTime.setTime(accessToken.getExpirationTime());
expirationTime.add(Calendar.MINUTE,-REFRESH_MINUTES); //refresh some time before expiry
creds = new Credential(BearerToken.authorizationHeaderAccessMethod());
creds.setAccessToken(accessToken.getAccessToken());
}
public SpreadsheetUtil(String appname) {
myService = new SpreadsheetService(appname);
myService.setOAuth2Credentials(cred);
}
Make sure to creds.refreshToken() or reinitialize when they expire.

How to encrypt SOAP messages manually?

I use JBoss 4.2.3.GA. In previous task I've used base encryption mechanism which JBoss supports (WS-Security). I.e. I used keystore, truststore files for encryption and signing messages. As usually (in standard way) in jboss-wsse-* files were defined aliases of keys that must be used during crypt process. I used ws security configuration from JBoss in Action book.
That's Ok. Encryption works fine.
But in my current task I need to specify aliases for keys manually and dynamically.
Task description:
I have several profiles. In every profile can be specifiey alias of public key that must be used for encrypting message.
I have keystore containing private/public key of server and public keys of clients that will send message to server
I need get alias from profile and encrypt message (on client side) using public key specified by this alias.
So I need somehow to load data from keystore (it must resides in file system folder, i.e. outside ear file), get appropriate public key from it and then do encryption.
After that I need to send message to remote web service (server side) that has private keys for decryption.
Here I see several variants for server side logic: web service makes decryption using standard JBoss mechanism or I can do it manually loading keystore data and do decryption manually.
So the questions are about:
Is there a way to specify for JBoss the file system directory to load keystores from?
Can I specify alias for encryption for standard JBoss WSS mechanism to allow jboss to use this information in crypt process?
If I must to do manual encryption/decryption then How can I wrap several Java-objects into WS message and then encrypt it using necessary alias and how to send this message to remote web service manually?
I just don't know how to start, what framework to use and even is it necessary to use external (non JBoss) frameworks for this...
If possible you can use Axis2 and Rampart. I've successfully used them both in a similar situation.
Rampart is an axis2 module for handling security and it exposes an API that allows you to define the key store location and aliases that you want to use, thus allowing you to define it dynamically.
Axis2
Rampart
Sample code:
private static final String CONFIGURATION_CTX = "src/ctx";
private static final String KEYSTORE_TYPE = "org.apache.ws.security.crypto.merlin.keystore.type";
private static final String KEYSTORE_FILE = "org.apache.ws.security.crypto.merlin.file";
private static final String KEYSTORE_PWD = "org.apache.ws.security.crypto.merlin.keystore.password";
private static final String PROVIDER = "org.apache.ws.security.components.crypto.Merlin";
private static void engageRampartModules(Stub stub)
throws AxisFault, FileNotFoundException, XMLStreamException {
ServiceClient serviceClient = stub._getServiceClient();
engageAddressingModule(stub);
serviceClient.engageModule("rampart");
serviceClient.engageModule("rahas");
RampartConfig rampartConfig = prepareRampartConfig();
attachPolicy(stub,rampartConfig);
}
/**
* Sets all the required security properties.
* #return rampartConfig - an object containing rampart configurations
*/
private static RampartConfig prepareRampartConfig() {
String certAlias = "alias"; //The alias of the public key in the jks file
String keyStoreFile = "ctx/client.ks";
String keystorePassword = "pwd";
String userName = "youusename";
RampartConfig rampartConfig = new RampartConfig();
//Define properties for signing and encription
Properties merlinProp = new Properties();
merlinProp.put(KEYSTORE_TYPE, "JKS");
merlinProp.put(KEYSTORE_FILE,keyStoreFile);
merlinProp.put(KEYSTORE_PWD, keystorePassword);
CryptoConfig cryptoConfig = new CryptoConfig();
cryptoConfig.setProvider(PROVIDER);
cryptoConfig.setProp(merlinProp);
//Rampart configurations
rampartConfig.setUser(userName);
rampartConfig.setUserCertAlias(certAlias);
rampartConfig.setEncryptionUser(certAlias);
rampartConfig.setPwCbClass("com.callback.tests.PasswordCallbackHandler"); //Password Callbak class
rampartConfig.setSigCryptoConfig(cryptoConfig);
rampartConfig.setEncrCryptoConfig(cryptoConfig);
return rampartConfig;
}
/**
* attach the security policy to the stub.
* #param stub
* #param rampartConfig
* #throws XMLStreamException
* #throws FileNotFoundException
*/
private static void attachPolicy(Stub stub, RampartConfig rampartConfig) throws XMLStreamException, FileNotFoundException {
Policy policy = new Policy();
policy.addAssertion(rampartConfig);
stub._getServiceClient().getAxisService().getPolicySubject().attachPolicy(policy);
}
PasswordCallbackHandler:
import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
public class PasswordCallbackHandler implements CallbackHandler {
// #Override
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();
switch (pwcb.getUsage()) {
case WSPasswordCallback.USERNAME_TOKEN: {
if (id.equals("pwd")) {
pwcb.setPassword("pwd");
}
}
}
}
}
}
1&2: Defining keystore for jboss:
<jboss-ws-security xmlns="http://www.jboss.com/ws-security/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.jboss.com/ws-security/config
http://www.jboss.com/ws-security/schema/jboss-ws-security_1_0.xsd">
<key-store-file>WEB-INF/wsse.keystore</key-store-file>
<key-store-password>jbossws</key-store-password>
<trust-store-file>WEB-INF/wsse.truststore</trust-store-file>
<trust-store-password>jbossws</trust-store-password>
<config>
<sign type="x509v3" alias="wsse"/>
<requires>
<signature/>
</requires>
</config>
</jboss-ws-security>
3: Encryption replacement (and manual too) example described here for axis2: http://www.javaranch.com/journal/2008/10/web-service-security-encryption-axis2.html

Categories