authentication with cognito aws in android studio - amazon-web-services

Hi I'm realizing the authentication with aws cognito I created the link between aws and android through this class:
import android.content.Context;
import java.util.HashMap;
import java.util.Map;
import com.amazonaws.auth.CognitoCachingCredentialsProvider;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoUserPool;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoUserSession;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
public class Cognito {
public final static String USER_POOL_ID = "USER_POOL_ID";
public final static String IDENTITY_POOL_ID = "IDENTITY_POOL_ID";
public final static String CLIENT_ID = "CLIENT_ID";
public final static String CLIENT_SECRET = null;
public final static Regions REGION = Regions.US_EAST_1;
private static Cognito cognito;
private final CognitoUserPool cognitoUserPool;
private final CognitoCachingCredentialsProvider cognitoCachingCredentialsProvider;
private Cognito(Context context) {
cognitoUserPool = new CognitoUserPool(
context,
USER_POOL_ID,
CLIENT_ID,
CLIENT_SECRET,
REGION
);
cognitoCachingCredentialsProvider = new CognitoCachingCredentialsProvider(
context,
IDENTITY_POOL_ID,
REGION
);
}
public CognitoUserPool getCognitoUserPool() {
return cognitoUserPool;
}
public static Cognito getInstance(Context context) {
if(cognito != null)
return cognito;
return (cognito = new Cognito(context));
}
public void setLogin(CognitoUserSession session) {
cognitoCachingCredentialsProvider.clear();
Map<String,String> login = new HashMap<>();
login.put(
"cognito-idp." + Region.getRegion(REGION) + ".amazonaws.com/" + USER_POOL_ID,
session.getIdToken().getJWTToken()
);
cognitoCachingCredentialsProvider.setLogins(login);
}
}
but I have the following errors when I upload the data and click the button for user registration:
E/AWSKeyValueStore: com.amazonaws.internal.keyvaluestore.KeyNotFoundException: Error occurred while accessing AndroidKeyStore to retrieve the key for keyAlias: com.amazonaws.android.auth.aesKeyStoreAlias
I/AWSKeyValueStore: Deleting the encryption key identified by the keyAlias: com.amazonaws.android.auth.aesKeyStoreAlias
E/AWSKeyValueStore: Error in retrieving the decryption key used to decrypt the data from the persistent store. Returning null for the requested dataKey = IDENTITY_POOL_ID.identityId
E/AWSKeyValueStore: com.amazonaws.internal.keyvaluestore.KeyNotFoundException: Error occurred while accessing AndroidKeyStore to retrieve the key for keyAlias: com.amazonaws.android.auth.aesKeyStoreAlias
I/AWSKeyValueStore: Deleting the encryption key identified by the keyAlias: com.amazonaws.android.auth.aesKeyStoreAlias
E/AWSKeyValueStore: Error in retrieving the decryption key used to decrypt the data from the persistent store. Returning null for the requested dataKey = IDENTITY_POOL_ID.expirationDate
D/NetworkSecurityConfig: No Network Security Config specified, using platform default
how can i solve?

Related

Amazon Cognito Identity with API Gateway

I'm develop app IOS and Android with Xamarin cross-platform.
I'm trying hard to use credentials receiving from Cognito Identity to authorize app invoking API Gateway.
My user flow is:
Authenticate on Cognito User Pool and get tokens
Exchange tokens for credentials on Cognito Identity Pools
Access API Gateway using credentials retrieved in the previous step.
Step 1 and 2 seems to works fine. But when app try to connect to api gateway it's getting error 403 (Forbidden).
My code:
Authenticate on Cognito User Pool and get tokens
**
public async Task<AppUser> Login(string username, string password)
{
CognitoUser cognitoUser = new CognitoUser(username, Aws.COGNITO_CLIENT_ID, CognitoUserPool, CognitoIdentityProviderClient);
AppUser appUser = new AppUser() { Email = username };
// Send a login request and wait for the response from Amazon
try
{
AuthFlowResponse response = await cognitoUser.StartWithSrpAuthAsync(new InitiateSrpAuthRequest()
{
Password = password
});
;
appUser.IsAuthenticated = true;
}
catch (NotAuthorizedException e)
{
appUser.IsAuthenticated = false;
appUser.ErrorMessage = e.Message;
}
await _tokenManagement.SaveTokens(cognitoUser.SessionTokens) ;
return appUser;
}
Exchange tokens for credentials on Cognito Identity Pools
**
public async Task<ImmutableCredentials> GetAppCredentialsAsync()
{
CognitoAWSCredentials cac;
if (_tokenManagement.CheckIsAnonymous())
{
//Anonymous credentials
cac = new CognitoAWSCredentials(Aws.COGINITO_IDENTITY_POLL_ID, RegionEndpoint.USEast1);
}
else
{
//Retrieve saved tokens from previous authentication
var tm = await _tokenManagement.RetrieveTokens();
CognitoUser user = new CognitoUser(null, Aws.COGNITO_CLIENT_ID, CognitoUserPool, CognitoIdentityProviderClient)
{
SessionTokens = new CognitoUserSession(tm.IdToken, tm.AccessToken, tm.RefreshToken, tm.IssuedTime, tm.ExpirationTime)
};
//Retrieve authenticated credentials
cac = user.GetCognitoAWSCredentials(Aws.COGINITO_IDENTITY_POLL_ID, RegionEndpoint.USEast1);
}
}
return await cac.GetCredentialsAsync();
}
Access API Gateway using credentials retrieved in the previous step:
**
public async Task<IList<MediaImage>> GetCoversAWSAsync()
{
// Getting credentials and sign request
var request = await BuildRequestAsync("/listMedia");
var client = new HttpClient();
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
IList<MediaImage> covers = JsonConvert.DeserializeObject<IList<MediaImage>>(await response.Content.ReadAsStringAsync());
return covers;
}
private async Task<HttpRequestMessage> BuildRequestAsync(string service)
{
var request = new HttpRequestMessage()
{
Method = HttpMethod.Get,
RequestUri = new Uri(baseURL + service)
};
ImmutableCredentials awsCredential = await _loginService.GetAppCredentialsAsync( );
var signer = new AWS4RequestSigner(awsCredential.AccessKey, awsCredential.SecretKey);
request = await signer.Sign(request, "execute-api", awsRegion);
return request;
}
This code works fine when I hard code credentials from one IAM user. But credentials retrieved from Cognito Identities its getting Forbidden error.
I did a test using SDK for S3 and I was able to successfully list the buckets with the same credentials received from Cognito Identities, but it is not possible to make requests on the API Gateway.
Can you help me? Where did I get lost?
I figure out what was going on.
After ensuring that the permissions settings were correct on AWS.
I found in the documentation that it is necessary to include in the HTTP header the token returned by the cognito (header name x-amz-security-token). So I changed the code to the following:
private async Task<HttpRequestMessage> BuildRequestAsync(string service)
{
var request = new HttpRequestMessage()
{
Method = HttpMethod.Get,
RequestUri = new Uri(baseURL + service)
};
ImmutableCredentials awsCredential = await _loginService.GetAppCredentialsAsync( );
//This where I add header to the HTTP request
request.Headers.Add("x-amz-security-token", awsCredential.Token);
var signer = new AWS4RequestSigner(awsCredential.AccessKey, awsCredential.SecretKey);
request = await signer.Sign(request, "execute-api", awsRegion);
return request;
}

Creating an add user interface using Aws Cognito

I want to make an app that main user can add other low privilege users(by their mail address). I made a cognito interface for signup but the user can not add another users. What kind of structure is suitable for this kind of job in aws?
Check https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminCreateUser.html
A small example in Java:
private static final AWSCognitoIdentityProvider COGNITO = AWSCognitoIdentityProviderClientBuilder.defaultClient();
#Override
public String execute(CreateCognitoUserRequest input, Context context) {
AdminCreateUserResult result = COGNITO.adminCreateUser(new AdminCreateUserRequest()
.withUsername(input.getEmail())
.withUserAttributes(getUserAttributes(input))
.withUserPoolId(System.getenv("COGNITO_USER_POOL_ID")));
return result.getUser().toString();
}
private List<AttributeType> getUserAttributes(CreateCognitoUserRequest input) {
ArrayList<AttributeType> attributes = new ArrayList<>();
attributes.add(new AttributeType().withName("email").withValue(input.getEmail()));
attributes.add(new AttributeType().withName("email_verified").withValue("true"));
attributes.add(new AttributeType().withName("phone_number").withValue(input.getPhoneNumber()));
attributes.add(new AttributeType().withName("custom:role").withValue(input.getRole()));
return attributes;
}

Amazon SES 403 error

I am trying to use Amazon SES to send email to my corporate account. I have copied by aws access keys to ~/.aws/credentials file. Seems i am consistently getting the error:
Error message: The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
The Canonical String for this request should have been
'POST
/
amz-sdk-invocation-id:638ed10a-22cd-12f5-c9a5-25a672a6c38d
amz-sdk-retry:3/136/485
host:email.us-east-1.amazonaws.com
user-agent:aws-sdk-java/1.11.172 Mac_OS_X/10.11.5 Java_HotSpot(TM)_64-Bit_Server_VM/25.60-b23/1.8.0_60
x-amz-date:20170808T040309Z
amz-sdk-invocation-id;amz-sdk-retry;host;user-agent;x-amz-date
1c21e3af09924eec311e370c8e6710c0bc3fa2027fe213db11f02b22d79b6c91'
The String-to-Sign should have been
'AWS4-HMAC-SHA256
20170808T040309Z
20170808/us-east-1/ses/aws4_request
82a2179c0dda36b0a4f80c111a8119cc8a65d768a0ff65de4c9b7ccf69a6b68a' (Service: AmazonSimpleEmailService; Status Code: 403; Error Code: SignatureDoesNotMatch; Request ID: 7dbfbcaa-7bee-11e7-a445-27be327c79a0)
com.amazonaws.services.simpleemail.model.AmazonSimpleEmailServiceException: The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
The Canonical String for this request should have been
'POST
/
amz-sdk-invocation-id:638ed10a-22cd-12f5-c9a5-25a672a6c38d
amz-sdk-retry:3/136/485
host:email.us-east-1.amazonaws.com
user-agent:aws-sdk-java/1.11.172 Mac_OS_X/10.11.5 Java_HotSpot(TM)_64-Bit_Server_VM/25.60-b23/1.8.0_60
x-amz-date:20170808T040309Z
amz-sdk-invocation-id;amz-sdk-retry;host;user-agent;x-amz-date
1c21e3af09924eec311e370c8e6710c0bc3fa2027fe213db11f02b22d79b6c91'
The String-to-Sign should have been
'AWS4-HMAC-SHA256
20170808T040309Z
20170808/us-east-1/ses/aws4_request
82a2179c0dda36b0a4f80c111a8119cc8a65d768a0ff65de4c9b7ccf69a6b68a' (Service: AmazonSimpleEmailService; Status Code: 403; Error Code: SignatureDoesNotMatch; Request ID: 7dbfbcaa-7bee-11e7-a445-27be327c79a0)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1587)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1257)
Code base:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.ByteBuffer;
import java.util.Properties;
import java.util.UUID;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import com.amazonaws.AmazonClientException;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceClient;
import com.amazonaws.services.simpleemail.model.RawMessage;
import com.amazonaws.services.simpleemail.model.SendRawEmailRequest;
public class SESClient {
private static String EMAIL_FROM = "##########";
private static String EMAIL_REPLY_TO = "##########";
private static String EMAIL_RECIPIENT = "##########";
// Remember to use two slashes in place of each slash.
private static Regions AWS_REGION = Regions.US_EAST_1;
private static String EMAIL_SUBJECT = "Amazon SES email test";
private static String EMAIL_BODY_TEXT = "This MIME email was sent through Amazon SES using SendRawEmail.";
public static void main(String[] args) throws AddressException, MessagingException, IOException {
Session session = Session.getDefaultInstance(new Properties());
MimeMessage message = new MimeMessage(session);
message.setSubject(EMAIL_SUBJECT, "UTF-8");
message.setFrom(new InternetAddress(EMAIL_FROM));
message.setReplyTo(new Address[]{new InternetAddress(EMAIL_REPLY_TO)});
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(EMAIL_RECIPIENT));
// Cover wrap
MimeBodyPart wrap = new MimeBodyPart();
// Alternative TEXT/HTML content
MimeMultipart cover = new MimeMultipart("alternative");
MimeBodyPart html = new MimeBodyPart();
cover.addBodyPart(html);
wrap.setContent(cover);
MimeMultipart content = new MimeMultipart("related");
message.setContent(content);
content.addBodyPart(wrap);
String[] attachmentsFiles = new String[]{
//EMAIL_ATTACHMENTS
};
StringBuilder sb = new StringBuilder();
for (String attachmentFileName : attachmentsFiles) {
String id = UUID.randomUUID().toString();
sb.append("<img src=\"cid:");
sb.append(id);
sb.append("\" alt=\"ATTACHMENT\"/>\n");
MimeBodyPart attachment = new MimeBodyPart();
DataSource fds = new FileDataSource(attachmentFileName);
attachment.setDataHandler(new DataHandler(fds));
attachment.setHeader("Content-ID", "<" + id + ">");
attachment.setFileName(fds.getName());
content.addBodyPart(attachment);
}
html.setContent("<html><body><h1>HTML</h1>\n" + EMAIL_BODY_TEXT + "</body></html>", "text/html");
try {
System.out.println("Attempting to send an email through Amazon SES by using the AWS SDK for Java...");
/*
* The ProfileCredentialsProvider will return your [default]
* credential profile by reading from the credentials file
* located at
* (~/.aws/credentials).
*
* TransferManager manages a pool of threads, so we create a
* single instance and share it throughout our application.
*/
AWSCredentials credentials = null;
try {
credentials = new ProfileCredentialsProvider().getCredentials();
} catch (Exception e) {
throw new AmazonClientException(
"Cannot load the credentials from the credential profiles file. " +
"Please make sure that your credentials file is at the correct " +
"location (~/.aws/credentials), and is in valid format.",
e);
}
AmazonSimpleEmailServiceClient client = new AmazonSimpleEmailServiceClient(credentials);
Region REGION = Region.getRegion(AWS_REGION);
client.setRegion(REGION);
// Print the raw email content on the console
PrintStream out = System.out;
message.writeTo(out);
// Send the email.
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
message.writeTo(outputStream);
RawMessage rawMessage = new RawMessage(ByteBuffer.wrap(outputStream.toByteArray()));
SendRawEmailRequest rawEmailRequest = new SendRawEmailRequest(rawMessage);
client.sendRawEmail(rawEmailRequest);
System.out.println("Email sent!");
} catch (Exception ex) {
System.out.println("Email Failed");
System.err.println("Error message: " + ex.getMessage());
ex.printStackTrace();
}
}
}

How to access user's email address in Cognito Federated Identities?

I'm trying to set up a basic website (serverless on AWS) that would allow visitors to login with Google and/or Facebook. Currently I'm planning to use S3, Cognito with Federated Identities, API Gateway, Lambda (NodeJS), with DynamoDB. The client app will be using Angular.
I have the social login with Google and Facebook working, and currently I am inserting a row in a "users" table when a user logs in the first time that includes the cognitoId, name, profile picture URL, etc.
I also figure it would be a good design to store the user's information with their email address as the key, instead of something like the cognitoId so that the user can login using different Providers and see the same data. So I need to know the authenticated user's email address, but I figure it should come from Cognito and not straight from the user (since the client app shouldn't be trusted).
I believe that Cognito is storing the user's email address because I have enabled that field as required int the User Pool.
The issue I'm having is that I cannot find any information about how to get the user's email address from Cognito.
The closest that I've come is this post, but I can't find the access token anywhere: How to get user attributes (username, email, etc.) using cognito identity id
This post indicates that I may be able to use GetUser, but I again don't know where the AccessToken comes from: creating user using AWS cognito identity
If I do need to use GetUser and the AccessToken, where does it come from, and how do I generate it? Does it come from the client, or can I get it in Lambda using AWS.config.credentials?
I've been trying to figure this out for a while now and I'm feeling like I'm missing something really simple!
Firstly, go into Cognito Identity provider (in the Cognito console) and make sure your provider "Authorize Scope" is suitable. For example if you clicked on the Google provider your Authorize scope might be "profile email openid". The scope will vary by provider, but whatever scope you are using, it must provide access to the users email.
When your user logs in with an external identity provider (lets say Facebook), Cognito negotiates with Facebook and then calls your Callback URL, which is set in the 'App Client Settings' part of the Cognito console. That Callback contains a parameter called 'code' - the parameter is set in the URL of the Callback made my Cognito. The code is an OAuth token.
Now you have an OAuth token in your client you need to POST that to the AWS Token Endpoint. The token endpoint returns three new tokens in the response; a JWT ID Token, a JWT Access Token and a refresh token. Take the "id_token" attribute from the endpoint response. Parse that id_token as a json string, and take the 'email' element. Now you should have the users email address.
Here is my working example in Java. This is a servlet that gets called by the Cognito Callback.
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.nimbusds.jwt.SignedJWT;
import net.minidev.json.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
public class CognitoLandingServlet extends HttpServlet {
static final Logger LOG = LoggerFactory.getLogger(CognitoLandingServlet.class);
private static final long serialVersionUID = 1L;
public CognitoLandingServlet() {
super();
}
#Override
protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
throws ServletException, IOException {
// Get the OpenID Connect (OAuth2) token passed back from the hosted Cognito
// Login Page
final String code = request.getParameter("code");
LOG.debug(String.format("Cognito OAuth2 code received from Cognito: %s.", code));
if (code != null) {
// do nothing, we have a code as expected
} else {
LOG.debug(String.format(
"Landing page requested without a Cognito code, the request probably didn't come from Cognito"));
// we dont have a token so redirect the user to the application sign in
// page
request.getRequestDispatcher("/signin").forward(request, response);
}
// Exchange the OIDC token for Cognito Access and ID JWT tokens using AWS
// Token
// Endpoint
// There does not appear to be a Java SDK to handle this :(
final String cognitoClientId = System.getProperty("CognitoClientId");
final String redirectUri = System.getProperty("CognitoCallBackUrl");
final String awsTokenEndpoint = System.getProperty("AwsTokenEndpoint");
final String jwt = swapOauthForJWT(cognitoClientId, code, redirectUri, awsTokenEndpoint);
// Complete the login using the JWT token string
loginWithJWT(jwt, request, response);
}
#Override
protected void doPost(final HttpServletRequest request, final HttpServletResponse response)
throws ServletException, IOException {
}
private void loginWithJWT(final String jwtString, final HttpServletRequest request,
final HttpServletResponse response) {
final JSONParser parser = new JSONParser();
SignedJWT signedIdJWT;
try {
// Take the id token
final JSONObject json = (JSONObject) parser.parse(jwtString);
final String idToken = (String) json.get("id_token");
// Access token is not currently used
// String accessToken = (String) json.get("access_token");
// Process the id token
signedIdJWT = SignedJWT.parse(idToken);
final String userId = signedIdJWT.getJWTClaimsSet().getSubject();
// Start NEW Session and start adding attributes
final HttpSession session = request.getSession(true);
session.setAttribute("userId", userId);
final String cognitoUsername = (String) signedIdJWT.getJWTClaimsSet()
.getClaim("cognito:username");
if (cognitoUsername != null) {
user.setUserName(cognitoUsername);
session.setAttribute("username", cognitoUsername);
}
final String email = (String) signedIdJWT.getJWTClaimsSet().getClaim("email");
if (email != null) {
user.setEmail(email);
session.setAttribute("email", email);
}
// Save the user to a database (code removed for stack overflow)
//request.getRequestDispatcher("/dashboard").forward(request, response);
response.sendRedirect("/dashboard");
LOG.info(
String.format("A user with userid %s and email %s successfully signed in", userId, email));
} catch (final java.text.ParseException e) {
LOG.error(
String.format("The JWT token could not be parsed by JOSE library. %s", e.getMessage()));
} catch (final ParseException e) {
LOG.error(String.format("The JWT token could not be parsed by JSON simple library. %s",
e.getMessage()));
} catch (final IOException e) {
LOG.error(String.format("Failed to request webpage at the end of the login process - io. %s",
e.getMessage()));
}
}
private String swapOauthForJWT(final String cognitoClientId, final String oauthCode,
final String redirectUri, final String awsTokenEndpoint) throws IOException {
// Build the URL to post to the AWS Token Endpoint
final String urlParameters = String.format(
"Content-Type=application/x-www-form-urlencoded&grant_type=authorization_code&client_id=%s&code=%s&redirect_uri=%s",
cognitoClientId, oauthCode, redirectUri);
LOG.debug(String.format("User is swapping OAuth token for a JWT using URL %s", urlParameters));
final URL url = new URL(awsTokenEndpoint);
final URLConnection conn = url.openConnection();
conn.setDoOutput(true);
final OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(urlParameters);
writer.flush();
// Read the data returned from the AWS Token Endpoint
final BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
final StringBuilder responseStrBuilder = new StringBuilder();
String inputStr;
while ((inputStr = reader.readLine()) != null) {
responseStrBuilder.append(inputStr);
}
// Close the connection
writer.close();
reader.close();
LOG.debug(String.format("Finished swapping OAuth token for a JWT"));
return responseStrBuilder.toString();
}
}
You also need to add Attribute mappings in your user pool. Check if you have forgotten to add the mappings. You can find "attribute mappings" tab under "federation" inside your User Pool settings
To get the email, you have to request it to the identity provider (facebook, google, user pool).
To get the email from the user pool you have to do something like:
cognitoUser.getUserAttributes(function(err, result) {
if (err) {
alert(err);
return;
}
for (i = 0; i < result.length; i++) {
console.log('attribute ' + result[i].getName() + ' has value ' + result[i].getValue());
}
});
Cognito Identity doesn't save the emails.

Using RemoteRegistry for exporting resource of a tenant

In WSO2 apim 1.10.0, I created a tenant with domain ofer.com, with admin username ofer, password admin
I'm able to login to carbon management console UI for this tenant using credentials ofer#ofer.com, password: admin.
Now I'm trying to use RemoteRegistry in order to export the tiers.xml of that tenant.
Here is the code:
import java.io.File;
import java.net.URL;
import org.wso2.carbon.registry.app.RemoteRegistry;
import org.wso2.carbon.registry.core.utils.RegistryClientUtils;
public class test {
private static String serverHostname = "...";
public static void main(String[] args) throws Exception {
System.setProperty("javax.net.ssl.trustStore", "p:/main/test/wso2carbon.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "wso2carbon");
System.setProperty("javax.net.ssl.trustStoreType","JKS");
System.setProperty("carbon.repo.write.mode", "true");
RemoteRegistry remote_registry = new RemoteRegistry(new URL("https://" + serverHostname + ":9443/registry"), "ofer#ofer.com", "admin");
File toFile = new File("e:/tiers.xml");
RegistryClientUtils.exportFromRegistry( toFile, "/_system/governance/apimgt/applicationdata/tiers.xml" ,remote_registry);
}
}
When I run this code with credentials admin/admin:
RemoteRegistry remote_registry = new RemoteRegistry(new URL("https://" + serverHostname + ":9443/registry"), "admin", "admin");
It runs successfully, but with
RemoteRegistry remote_registry = new RemoteRegistry(new URL("https://" + serverHostname + ":9443/registry"), "ofer#ofer.com", "admin");
I get a "unatuthorized" exception:
Exception in thread "main" org.wso2.carbon.registry.core.exceptions.RegistryException: Failed to export from registry
at org.wso2.carbon.registry.core.utils.RegistryClientUtils.exportFromRegistry(RegistryClientUtils.java:89)
at test.main(test.java:26)
Caused by: org.wso2.carbon.registry.core.exceptions.RegistryException: Unauthorized
at org.wso2.carbon.registry.app.RemoteRegistry.get(RemoteRegistry.java:174)
at org.wso2.carbon.registry.core.utils.RegistryClientUtils.processExport(RegistryClientUtils.java:123)
at org.wso2.carbon.registry.core.utils.RegistryClientUtils.exportFromRegistry(RegistryClientUtils.java:86)
... 1 more
Any idea what I have missed? Is there anywhere I should grant access to ofer#ofer.com to do the export?
/// EDITED ///
I see now that there is another class, RemoteRegistryService for getting a user registry. I'm trying:
RemoteRegistryService registryService = new RemoteRegistryService("http://" + serverHostname + ":9763/registry", "admin", "admin");
UserRegistry ur = registryService.getSystemRegistry(...)
For this to work I see that it requires a realm service. How do I get hold of that?
Found it out.
The URL should include the tenant domain, i.e. instead of
http://localhost:9443/registry
http://localhost:9443/t//registry
Updated code:
import java.io.File;
import java.net.URL;
import org.wso2.carbon.registry.app.RemoteRegistry;
import org.wso2.carbon.registry.core.utils.RegistryClientUtils;
public class test {
private static String serverHostname = "...";
public static void main(String[] args) throws Exception {
System.setProperty("javax.net.ssl.trustStore", "p:/main/test/wso2carbon.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "wso2carbon");
System.setProperty("javax.net.ssl.trustStoreType","JKS");
System.setProperty("carbon.repo.write.mode", "true");
RemoteRegistry remote_registry = new RemoteRegistry(new URL("https://" + serverHostname + ":9443/t/ofer.com/registry"), "ofer#ofer.com", "admin");
File toFile = new File("e:/tiers.xml");
RegistryClientUtils.exportFromRegistry( toFile, "/_system/governance/apimgt/applicationdata/tiers.xml" ,remote_registry);
}
}