I can create a ProjectApiRoot using the Java SDK and perform requests with that using the following code:
private static ProjectApiRoot createProjectClient() {
ProjectApiRoot apiRoot = ApiRootBuilder.of()
.defaultClient(ClientCredentials.of()
.withClientId(System.getenv("CTP_CLIENT_ID"))
.withClientSecret(System.getenv("CTP_CLIENT_SECRET"))
.build(),
ServiceRegion.GCP_EUROPE_WEST1)
.build(System.getenv("CTP_PROJECT_KEY"))
return apiRoot
}
However, I would like to authorize as a specific customer (email and password) and interact with the Commercetools API using the customer. The following code throws an error:
private static ProjectApiRoot createCustomerClient() {
def tokenUri = "https://auth.europe-west1.gcp.commercetools.com/oauth/*CTP_PROJECT_KEY*/customers/token"
def projectKey = System.getenv("CTP_PROJECT_KEY")
def scopes = System.getenv("CTP_SCOPES")
def credentials = ClientCredentials.of()
.withClientId("*email*")
.withClientSecret("*password*")
.withScopes(scopes)
.build()
def apiRootBuilder = ApiRootBuilder.of()
.withApiBaseUrl("https://api.europe-west1.gcp.commercetools.com")
.withClientCredentialsFlow(credentials, tokenUri)
return apiRootBuilder.build(projectKey)
}
Error:
io.vrap.rmf.base.client.oauth2.AuthException: detailMessage: Unauthorized
"message" : "Please provide valid client credentials using HTTP Basic Authentication.",
By using the withGlobalCustomerPasswordFlow instead of the withClientCredentialsFlow which authenticates the customer prior to doing the request.
But I would advise to do this only in a context where the customer is logging in everytime. Using it in any other context e.g. remembered log in of needs a more sophisticated approach as you need to store the bearer token and refresh token and can't easily use the middleware approach for authenticating the customer but instead do it not as part of an auth flow middleware.
Please see also https://github.com/commercetools/commercetools-sdk-java-v2/tree/main/commercetools/commercetools-sdk-java-api/src/integrationTest/java/commercetools/me
Related
I am trying to implement some LDAP authentication using the ldaptive library. In their examples they reference a class named SimpleBindAuthenticationHandler, but I cannot find where this class is defined... anywhere! Google doesn't seem to know where it is, nor Github, nor Oracle. I'm truly at a loss for where this class is and I cannot implement the LDAP code as they have given in their example without it.
ConnectionConfig connConfig = ConnectionConfig.builder()
.url("ldap://directory.ldaptive.org")
.useStartTLS(true)
.build();
SearchDnResolver dnResolver = SearchDnResolver.builder()
.factory(new DefaultConnectionFactory(connConfig))
.dn("ou=people,dc=ldaptive,dc=org")
.filter("uid={user}")
.build();
SimpleBindAuthenticationHandler authHandler = new SimpleBindAuthenticationHandler(new DefaultConnectionFactory(connConfig));
Authenticator auth = new Authenticator(dnResolver, authHandler);
AuthenticationResponse response = auth.authenticate(new AuthenticationRequest("dfisher", new Credential("password")));
if (response.isSuccess()) {
// authentication succeeded
} else {
// authentication failed
}
so I'm trying to use this library library
to access my Spotify account but i can't figure out how i can get an acces token but i can't figure out how i can get the response from the authorization URL I have trayed creating a input stream that access the url and print out the response but i dos not give the right output i have also trayed creating a server with shut receive the response but I'm getting nothing i have never used java server / networking that much so i might have made an error....
public class privat {
public privat() throws IOException {
final String clientId = "clientId ";
final String clientSecret = "clientSecret code ";
final String redirectUri = "http://localhost:8888/callback";
final Api api = Api.builder()
.clientId(clientId)
.clientSecret(clientSecret)
.redirectURI(redirectUri)
.build();
/* Set the necessary scopes that the application will need from the user */
final List<String> scopes = Arrays.asList("user-read-private", "user-read-email");
/* Set a state. This is used to prevent cross site request forgeries. */
final String state = "someExpectedStateString";
String authorizeURL = api.createAuthorizeURL(scopes, state);
System.out.println(authorizeURL);
/* Continue by sending the user to the authorizeURL, which will look something like
https://accounts.spotify.com:443/authorize?client_id=5fe01282e44241328a84e7c5cc169165&response_type=code&redirect_uri=https://example.com/callback&scope=user-read-private%20user-read-email&state=some-state-of-my-choice
*/
/* Application details necessary to get an access token */
final String code = "" ;/* where to find this ?? */
/* Make a token request. Asynchronous requests are made with the .getAsync method and synchronous requests
* are made with the .get method. This holds for all type of requests. */
final SettableFuture<AuthorizationCodeCredentials> authorizationCodeCredentialsFuture = api.authorizationCodeGrant(code).build().getAsync();
/* Add callbacks to handle success and failure */
Futures.addCallback(authorizationCodeCredentialsFuture, new FutureCallback<AuthorizationCodeCredentials>() {
#Override
public void onSuccess(AuthorizationCodeCredentials authorizationCodeCredentials) {
/* The tokens were retrieved successfully! */
System.out.println("Successfully retrieved an access token! " + authorizationCodeCredentials.getAccessToken());
System.out.println("The access token expires in " + authorizationCodeCredentials.getExpiresIn() + " seconds");
System.out.println("Luckily, I can refresh it using this refresh token! " + authorizationCodeCredentials.getRefreshToken());
/* Set the access token and refresh token so that they are used whenever needed */
api.setAccessToken(authorizationCodeCredentials.getAccessToken());
api.setRefreshToken(authorizationCodeCredentials.getRefreshToken());
}
#Override
public void onFailure(Throwable throwable) {
/* Let's say that the client id is invalid, or the code has been used more than once,
* the request will fail. Why it fails is written in the throwable's message. */
System.out.println(throwable.getMessage());
System.out.println(throwable.getStackTrace());
}
});
}
}
The code comes as a query parameter to your callback URL once the user authorises your application. You'll need to find a way to grab it from there - you could spin up a web server on localhost:8888 to get the code from there - or you could instruct the user to copy the code from the query parameters of the redirect URI once they're redirected. You can find more information about the authorisation procedure (looks like either the authorization code or implicit grant flows will work for you) on the Spotify Developer site.
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.
I have the following Google Cloud Endpoints API, and I want it accesible only for authenticated users with certain role.
Few lines of code says much more than a thousand words:
import com.google.appengine.api.users.User;
#Api(
name = "heroesApi",
version = "v1",
clientIds = {...},
scopes = {...},
audiences = {...},
namespace = #ApiNamespace(
ownerDomain = "my.domain.com",
ownerName = "my.domain.com",
packagePath=""
)
)
public class HeroesApi {
// THIS IS THE FUNCTION THAT I DON´T KNOW WHERE TO PUT
/**
* Validates that the user is logged in with a specific role
* #param user
* #throws UnauthorizedException
* #throws ForbiddenException
*/
private void validateUser(User user) throws UnauthorizedException, ForbiddenException {
IUserController userController = ControllerFactory.get.userController();
if (user == null) {
throw new ForbiddenException("You must be logged in, my friend.");
} else if (!userController.isLoggedAsSuperHero(user)) {
throw new UnauthorizedException("You must be logged in as a Superhero.");
}
}
// API METHODS
#ApiMethod(path = "something", httpMethod = ApiMethod.HttpMethod.PUT)
public DoneTask doSomething(Some thing, User superhero) throws UnauthorizedException, ForbiddenException {
// this is what I want to avoid on each function
this.validateUser(superhero);
// Now I'll do something special
IUserController userController = ControllerFactory.get.userController();
return userController.doSome(thing);
}
// MORE GORGEOUS METHODS JUST FOR SUPERHEROES, SO I HAVE TO PERFORM THE VALIDATION...
}
I have though about adding a filter through the web.xml file for all request to /api/heroesApi/*, but the problem there is how to catch the Google Appengine Api User.
Isn´t there something provided by Google to do this?
Any suggestion to avoid the repeated call to validateUser(User) is welcome
Google Cloud Endpoints doesn't supper roles by default , so your application have to build role concept, and you have to write filter and get current user and check against the roles maintained in your end
To get current user in the filter, try this
https://cloud.google.com/appengine/docs/java/oauth/
I haven't tested this , but am sure you can get the current user using the UserService Api in appengine as long as your system uses google account as authentication.
I am trying to write to Cloud Storage with the REST API using this code:
public static void insertData() {
try {
StorageObject st = new StorageObject();
//create the media object
Media m = new Media();
String content = "hi! this is a test";
m.setData(Base64.encodeBase64String(content.getBytes()));
m.setContentType("text/html");
st.setMedia(m);
//this gets me the credential, works for other APIs but not cloud storage
Storage storage = RequestBuilder.buildStorage();
//Create the insert and execute
Insert insert = storage.objects().insert("mybucket", st);
insert.execute();
} catch (IOException e) {
log.severe(e.getMessage());
}
}
This is my ACL entry as per the REST API:
"kind": "storage#bucketAccessControls",
"items": [
{
"kind": "storage#bucketAccessControl",
"id": "gammeprediction/allUsers",
"selfLink": "https://www.googleapis.com/storage/v1beta1/b/gammeprediction/acl/allUsers",
"bucket": "mybucket",
"entity": "allUsers",
"role": "OWNER"
}]
This is how I get the credential:
private static Credential authorize() {
GoogleCredential credential = null;
//load properties
Properties appProperties = new Properties();
appProperties.load(RequestBuilder.class
.getResourceAsStream("/app.properties"));
// creates an authorization with the key and service account given
InputStream is = RequestBuilder.class.getResourceAsStream("/"
+ appProperties.getProperty("app.keyFileName"));
PrivateKey pk;
try {
pk = PrivateKeys.loadFromKeyStore(KeyStore.getInstance("PKCS12"),
is, "notasecret", "privatekey", "notasecret");
credential = new GoogleCredential.Builder()
.setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(
appProperties
.getProperty("app.serviceAccount"))
.setServiceAccountPrivateKey(pk)
.setServiceAccountScopes(PredictionScopes.PREDICTION,
DriveScopes.DRIVE, StorageScopes.DEVSTORAGE_FULL_CONTROL).build();
return credential;
}
The permissions on the bucket are OWNER for allUsers, but I still get a 403 Forbidden "Access not configured" error. What could possibly be wrong?
Once the JSON API is generally available, this logic will work.
However, at the moment, the JSON API is in Limited Preview. Since an unknown user is not considered to be a member of the limited preview, completely anonymous queries via the REST API are currently not possible. Instead, you must provide at a bare minimum a whitelisted API key when you connect. If you provide no further identity information, you'll be treated as an anonymous user. Or, going further, you can use OAuth2 credentials instead to be treated as a registered user. For more, see: https://developers.google.com/storage/docs/json_api/
Is that a GWT RequestBuilder? I'm not entirely familiar with its use, unfortunately. If it helps, here's an example of setting up a connection with an API key using the Google API Java Client: https://code.google.com/p/google-api-java-client/wiki/OAuth2#Unauthenticated_access
Also, it looks like your call to setData() is passing a non-base64'd string, which will fail.