Authenticating to IBM Object Storage with OpenStack4j - java

I'm having a hard time authenticating to the Object Storage Service in IBM Cloud from an external Java application using the OpenStack4j library (version 3.1.0). Here's how I'm trying:
Identifier domainIdentifier = Identifier.byName("DOMAIN");
Identifier projectIdentifier= Identifier.byName("PROJECT");
OSClient.OSClientV3 os = OSFactory.builderV3()
.endpoint("https://identity.open.softlayer.com/v3")
.credentials("USER", "PASS")
.scopeToProject(projectIdentifier, domainIdentifier)
.authenticate();
References:
https://github.com/acloudfan/IBM-Object-Storage-Sample/
https://github.com/ibm-bluemix-mobile-services/bluemix-objectstorage-sample-liberty
The problem seems to be that I can't figure out where to get the DOMAIN and PROJECT information mentioned above, and perhaps the endpoint. The documentation says to obtain them from the Object Storage page under Service Credentials and View Credentials. I do see a JSON output with the following fields:
{
"apikey": "...",
"endpoints": "...",
"iam_apikey_description": "...",
"iam_apikey_name": "...",
"iam_role_crn": "...",
"iam_serviceid_crn": "...",
"resource_instance_id": "..."
}
None of which seem to relate to domain or project information, at least by name. I even created a separate Web App with an Object Storage Connector, and tried to obtain the information from the Environment Variables page, as some of the documentation suggested, but with no luck.
What I ultimately want to achieve is to be able to ingest files to a container I created, and use the data & analytics services on top (Data Science Experience).

The reason for the confusion is that there are (or used to be) two different Object Storage services on Bluemix (Object Storage and Cloud Object Storage). The bluemix-mobile-services SDK is written for the Object Storage one rather than the service you have provisioned.
The App Service page has a starter kit which makes it pretty easy to get starter code and set up with a toolchain for a Liberty project:
This has the domain field for the credentials. (Here is a link to the starter kits & I added the Object Storage service which injects the credentials: https://console.bluemix.net/developer/appservice/starter-kits. Or you can create a project with just the service and no code: https://console.bluemix.net/developer/appservice/create-project?services=Object-Storage)
Here is the documentation for the Java SDK for Cloud Object Storage if you would like to use that service instead:
https://console.bluemix.net/docs/services/cloud-object-storage/libraries/java.html#java
Here is a comparison of the Object Storage services:
https://console.bluemix.net/catalog/infrastructure/object-storage-group

Related

Get keyvault secrets using Spring api with Managed Service Identities

Due to some new security requirments the api I'm developing now is required to store several urls, azure account names etc. in the azure key vault, rather than in the application.yml config file.
The issue is that I'm having trouble authenticating / accessing the key vault client in a Local environment. I have very limited access to the azure functions / key vault itself so testing the new code I'm writing is near impossible at current:
public String getSecretFromKeyVault(String key) {
/**
* Breaks in the constructor call, as the system.env variables for MSI_ENDPOINT and MSI_SECRET are null.
**/
AppServiceMSICredentials credentials = new AppServiceMSICredentials(AzureEnvironment.AZURE);
KeyVaultClient client = new KeyVaultClient(credentials);
SecretBundle secret = client.getSecret("url-for-key-vault", key);
return secret.value();
}
I'm aware that the variables will be set in the cloud server, but my question is how can I best verify that the vault calls have been implemented properly(unit, integration, e2e local tests), and how would I manage to use key vault calls during local development / runtime?
The alternative to MSI would be to enter the client id and key manually, following authentication against the active directory. This could be a solution for local development, but Would still require the declaration of confidential information in the source code.
Ive also tried logging in to azure using az login before running the server but that didn't work either.
Does anyone have any suggestions on how I might resolve this issue, or what my best options are going forward?
Notes on application:
Java version: 8
Spring boot
Azure / vsts development and deployment environment
Since you're using spring-boot you may be better off using Microsoft's property source implementation that maps the keyvault properties into Spring properties and for local development and testing you set equivalent properties in property files.
Use Spring profiles. let's say you have azure and local profiles. In your application-azure.yml file configure your app to use keyvault:
# endpoint on the azure internal network for getting the identity access token
MSI_ENDPOINT: http://169.254.169.254/metadata/identity/oauth2/token
MSI_SECRET: unused
# this property triggers the use of keyvault for properties
azure.keyvault:
uri: https://<your-keyvault-name>.vault.azure.net/
Now you can inject secret properties from the spring context into your variables and they will be read from keyvault:
#Value("${superSecretValue}")
String secretValue;
To make this work locally for testing, in your application-local.yml file you can set the secret property to something appropriate:
superSecretValue: dummy-for-testing-locally
The Azure dependency you need to add to build.gradle is:
implementation "com.microsoft.azure:azure-keyvault-secrets-spring-boot-starter:2.1.6"
Run your spring-boot jar with azure as the active profile when deployed, and local when testing and developing away from azure. This is tested and working with azure java containers.

Using Xero's Java SDK to support authentication of multiple private apps?

I am using Xero's Java SDK to build my application. My application is now facing a requirement of having to work with several Xero private apps, therefore I need to manage and performing authentication (OAuth) via the key certificate file and appropriate consumer key and secret.
I was thinking to very simply store these details in a database table and retrieve them appropriately more or less as in the following:
// create a Xero config instance
Config config = JsonConfig.getInstance();
// build config file - details will be obtained from database
config.setConsumerKey("key");
config.setConsumerSecret("secret");
// this line will have me authenticate with the Xero service using the config file built
XeroClient client = new XeroClient(config);
The problem with this approach is that I am not pointing at the public_privatekey.pfx key file which is another essential element required to authenticate.
The reason why I am not doing so is that the SDK does not seem to support this using the Config instance as shown above - there is no option for me to select the appropriate public_private.pfx file (and neither an option for me to just load the contents of the file). It doesn't make sense to me that an SDK would be missing a feature, therefore questioning my approach; have I overlooked a detail or am I approaching the problem incorrectly?
Take a look at the read me under the heading Customize Request Signing
https://github.com/XeroAPI/Xero-Java/blob/master/README.md
You can provide your own signing mechanism by using the public XeroClient(Config config, SignerFactory signerFactory) constructor. Simply implement the SignerFactory interface with your implementation.
You can also provide a RsaSignerFactory using the public RsaSignerFactory(InputStream privateKeyInputStream, String privateKeyPassword) constructor to fetch keys from any InputStream.

How to access application in Tomcat with Context path

I have a web application which is developed with J2EE, GWT and hosting on Tomcat(version-7.0). I have webapp called "Courses"
which is plcaed in tomcat/webapps folder. I am accessing my "courses" application by using the following Url:
http://localhost:8085/Courses.
In my courses application i have so many slices like "physics", "maths" etc.I need to access "physics"
Now i want to access my application by entering the Url:
http://localhost:8085/Courses/physics
How can I run my courses application by entering the above URL.
In GWT you should use GWT's history mechanism for this.
The URL you wish http://localhost:8085/Courses/physics isn't really possible using GWT (or you must create multiple modules but that seems a big overkill for your situation).
But you could have an url like : http://localhost:8085/Courses#physics
Check : http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsHistory.html

Securing a jersey RESTful web service

I'm developing a restful web service that will be consumed by an Android application later on.
Right now, I'm seeking a way to secure the access to my resources:
I found several ways for implementing that on the net, but I can't figure out what is the most appropriate one.
For example, I found that Oauth specifications are more convenient for third-party applications which is not my case.
So what are the most suitable ways for securing jersey APIs, and I'll be glad if someone can provide me with any tutorials/documentations on that.
I'm using a Glassfish v4 server and the Jersey JAX-RS implementation.
After looking at different options I used an authentication filter and basic auth. Very easy to implement.
Some example code:
You need a filter
public class AuthFilter implements ResourceFilter, ContainerRequestFilter {
...
}
And a security context:
public class MySecurityContext implements SecurityContext {
...
}
And a user class:
public class User implements Serializable, Principal {
...
}
Finally, you can add the filters you need like so: (pass your ResourceConfig object to this function)
private void prepareFilters(ResourceConfig rc) {
rc.getProperties().put("com.sun.jersey.spi.container.ContainerRequestFilters",
getClassListing(new Class[]{
AuthFilter.class
}));
rc.getProperties().put("com.sun.jersey.spi.container.ContainerResponseFilters",
getClassListing(new Class[]{
CORSFilter.class, //You might not need this
GZIPContentEncodingFilter.class //You might not need this
}));
rc.getProperties().put("com.sun.jersey.spi.container.ResourceFilters",
getClassListing(new Class[]{
RolesAllowedResourceFilterFactory.class
}));
}
BTW, you can add #Context SecurityContext securityContext; to your resource class(es) or the individual methods for more fine grained access control. The SecurityContext will be injected into the context of your resource so you can access the User object per request with
With this setup you can annotate your REST methods with #PermitAll, #RolesAllowed, etc which gives you a good level of control over your RESTful interface.
I just finished my stateless (without sessions) user auth and management with Jersey.
Let me know if you want a full example or if you want to give it a try yourself ;)
The simplest way would be using the Java EE build-in Container Managed Security model to secure your rest resources as described in this tutorial. It allows you to configure the security based on users and roles stored in a database or file realm in the web.xml or the the classes themselves.
The disadvantage would be that you must start a session, extract the JSESSIONID and send it in each of your requests so that the server can verify it, but that makes your services more 'stateful' and violates the statelessness of the rest architecture.
Another way would be implementing custom security by using WebFilters, like sending the user name and password with each of your requests and verity them based on the information in a special db. If the information doesn't match the information stored in the database a redirect or a special error code can be returend in the Response object.
The best approach I think is using OAuth2 as described in this specification. Dependend on what kind of client you are using (desktop, web page, mobile client) there are different workflows and apart from that lots of benefits like creating tokens for special scopes of your application (read-only or full access,...). Google provides many different apis that can be accessed by the same account. If an applications only needs data from the calendar api, the requested token only gives you access to this special api and not to the entire resources of the account (like mail data, notes, etc). Another point would be that the security handling is decoupled from the client and no password must be stored in the client application.
You can either implement everything on your own or use a open source project like this. It provides a description on how it works and the code is very good but it has many dependencies to spring frameworks. For my use case I've startend replacing them by vanilla Java EE 7 code and create a solution based on the idea of this open source project. The reason behind the replacements was that it's more future-proof and it avoids class loader problems during the deployment.
In the Android app a Authenticator can be implemented for secure storing of the token.

Environment configuration management?

There is a team develops enterprise application with web interface: java, tomcat, struts, mysql, REST and LDAP calls to external services and so on.
All configuration is stored in context.xml --tomcat specific file that contains variables available via servlet context and object available via JNDI resources.
Developers have no access to production and QA platforms (as it should be) so context.xml is managed by support/sysadmin team.
Each release has config-notes.txt with instructions like:
please add "userLimit" variable to context.xml with value "123", rename "DB" resource to "fooDB" and add new database connection to our new server (you should know url and credentials) named "barDb"
That is not good.
Here is my idea how to solve it.
Each release has special config file with required variable names, descriptions and default values (if any): even web.xml could be used.
Here is pseudo example:
foo=bar
userLimit=123
barDb=SET_MANUAL(connection to our new server)
And there is a special tool that support team runs against deployment artifact.
Look at it (text after ">" is typed by support guy):
Config for version 123 of artifact "mySever".
Enter your config file location> /opt/tomcat/context/myServer.xml
+"foo" value "bar" -- already exists and would not be changed
+"userLimit" value "123" -- adding new
+"barDb"(connection to our new server) please type> jdbc:mysql:host/db
Saving your file as /opt/tomcat/context/myServer.xml
Your environment is not configured to run myServer-123.
That will give us ability to deploy application on any environment and update configuration if needed.
Do you like my idea? What do you use for environment configuration management? Does there is ready-to-use tools for that?
There are plenty of different strategies. All of them are good and depends on what suit you best.
Build a single artifact and deploy configs to a separate location. The artifact could have placeholder variables and, on deployment, the config could be read in. Have a look at Springs property placeholder. It works fantastically for webapps that use Spring and doesn't involve getting ops involved.
Have an externalised property config that lives outside of the webapp. Keep the location constant and always read from the property config. Update the config at any stage and a restart will be up the new values.
If you are modifying the environment (i.e. application server being used or user/group permissions) look at using the above methods with puppet or chef. Also have a look at managing your config files with these tools.
As for the whole should devs be given access to prod, it really depends on a per company basis. For smaller companies where the dev is called every time there is a problem, regardless of whether that problem is server or application related, then obviously devs require access to the box.
DevOps is not about giving devs access to the box, its about giving devs the ability to use infrastructure as a service, the ability to spawn new instances with application X with config Y and to push their applications into environments without ops. In a large company like ours, what it allows is the ability for devs to manage the application they put on a server. Operations shouldn't care what version is on their, thats our job, their job is all about keeping the server up and running.
I strongly disagree with your remark that devs shouldn't have access to prod or staging environments. It's this kind of attitude that leads to teams working against each other instead of with eath other.
But to answer your question: you are thinking about what is typically called continuous integration ( http://en.wikipedia.org/wiki/Continuous_integration ) and moving towards devops. Ideally you should aim for the magic "1 click automated deployment". The guys from Flickr wrote a lot of blogs (and books) about how they achieved that.
Anyhow .. there's a lot of tools around that sector. You may want to have a look a things like Hudson/Jenkins or Puppet/Chef.

Categories