我试图遵循这个和这个教程,但我不确定这是否应该这样做。我正在使用CognitoSync ,当我尝试启动Sync Service时,我遇到了“Identity_id and dataset_name not unique”的异常。
在 Amazon 控制台上,我创建了一个 IdentityPool 并将服务器端类的包名称,即“com.leversystems.devauth”作为 DeveloperProvider,并在服务器类和 Android 应用程序中使用它。在服务器类
map.put("com.leversystems.devauth", "someUniqueId");
在安卓应用中
logins.put("com.leversystems.devauth", cognitoProvider.getToken());
这是我的代码
Java 服务器端
package com.leversystems.devauth;
import java.util.HashMap;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.cognitoidentity.AmazonCognitoIdentityClient;
import com.amazonaws.services.cognitoidentity.model.GetOpenIdTokenForDeveloperIdentityRequest;
import com.amazonaws.services.cognitoidentity.model.GetOpenIdTokenForDeveloperIdentityResult;
public class DevAuth {
private BasicAWSCredentials credentials = null;
private String myAwsAccessKey = "myaccesskey";
private String myAwsSecretKey = "mysecretkey";
private String identityPoolID = "identityPoolid";
private String authARN = "arn:aws:iam::782936514542:role/DefaultRole";
private String identityId;
private String token;
public DevAuth()
{
identityId = "No id has been set yet!";
token = "No token has been set yet!";
initializeSecurity();
}
public String getToken()
{
return this.token;
}
public String getIdentityId()
{
return this.identityId;
}
public void initializeSecurity(){
credentials = new BasicAWSCredentials(myAwsAccessKey , myAwsSecretKey);
AmazonCognitoIdentityClient client =
new AmazonCognitoIdentityClient(credentials);
GetOpenIdTokenForDeveloperIdentityRequest tokenRequest =
new GetOpenIdTokenForDeveloperIdentityRequest();
tokenRequest.setIdentityPoolId(identityPoolID);
HashMap<String, String> map = new HashMap<String, String>();
map.put("com.leversystems.devauth", "nameid.number@provider.com");
//Duration of the generated OpenID Connect Token
tokenRequest.setLogins(map);
tokenRequest.setTokenDuration(1000l);
GetOpenIdTokenForDeveloperIdentityResult result
= client.getOpenIdTokenForDeveloperIdentity(tokenRequest);
this.identityId = result.getIdentityId();
this.token = result.getToken();
}}
我已经为这个类创建了一个 web 服务,在另一个类Bridge 类中我正在调用这个函数,它将令牌和 id 发送到 Android 应用程序。这工作正常,我在 Android 应用程序中获取 Token 和 IdentityId。
安卓类
MainActivity 类
package com.leversystems.authserver;
import java.util.HashMap;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.amazonaws.auth.AWSCognitoIdentityProvider;
import com.amazonaws.auth.CognitoCachingCredentialsProvider;
import com.amazonaws.mobileconnectors.cognito.CognitoSyncManager;
import com.amazonaws.mobileconnectors.cognito.Dataset;
import com.amazonaws.mobileconnectors.cognito.Dataset.SyncCallback;
import com.amazonaws.mobileconnectors.cognito.Record;
import com.amazonaws.mobileconnectors.cognito.SyncConflict;
import com.amazonaws.mobileconnectors.cognito.exceptions.DataStorageException;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.cognitoidentity.AmazonCognitoIdentity;
import com.amazonaws.services.cognitoidentity.model.GetOpenIdTokenForDeveloperIdentityRequest;
import com.amazonaws.services.cognitoidentity.model.GetOpenIdTokenForDeveloperIdentityResult;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
public class MainActivity extends Activity {
AWSCognitoIdentityProvider cognitoProvider;
CognitoCachingCredentialsProvider credentialsProvider;
AmazonCognitoIdentity identityClient;
GetOpenIdTokenForDeveloperIdentityRequest idRequest;
GetOpenIdTokenForDeveloperIdentityResult idResp;
CognitoSyncManager client;
Dataset dataset;
TextView tv1;
TextView tv2;
TextView tv3;
Button btn1;
Button btn2;
final String ACC_ID = "myAccountID";
final String IDENTITY_POOL_ID = "identityPoolId";
final String AUTHORIZATION_ARN = "DefaultRole";
final String ACCESS_KEY = "myAccessKey";
final String SECRET_KEY = "mySecretKey";
Credentials cred;
public class Credentials {
String identityId;
String token;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playerName = (TextView) findViewById(R.id.textView1);
currentLevel = (TextView) findViewById(R.id.textView2);
highScore = (TextView) findViewById(R.id.textView3);
btn1 = (Button) findViewById(R.id.button1);
btn2 = (Button) findViewById(R.id.button2);
btn3 = (Button) findViewById(R.id.button3);
initCognito();
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
displayCogntioSyncData();
}
});
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
addCognitoSyncData();
}
});
btn3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
wipeCognitoSyncData();
}
});
}
private void initCognito() {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
AsyncHttpClient client = new AsyncHttpClient();
client.get(
"http://192.168.1.112:8080/AuthenticationService/services/auth/gctbda",
new AsyncHttpResponseHandler() {
// When the response returned by REST has Http response code
// '200'
@Override
public void onSuccess(String response) {
try {
Gson gson = new Gson();
JsonParser jsonParser = new JsonParser();
JsonArray resultArray = jsonParser.parse(response)
.getAsJsonArray();
for (JsonElement credProvider : resultArray) {
cred = gson.fromJson(credProvider,
Credentials.class);
BYOIProvider.identityId = cred.identityId;
BYOIProvider.token = cred.token;
System.out.println("Id: " + cred.identityId);
System.out.println("Token: " + cred.token);
}
syncCognito();
} catch (Exception e) {
System.err.println("Exception in OnSuccess: "
+ e.getMessage());
}
}
});
}
private void syncCognito() {
cognitoProvider = new BYOIProvider(ACC_ID, IDENTITY_POOL_ID);
credentialsProvider = new CognitoCachingCredentialsProvider(
getApplicationContext(), cognitoProvider, null,
AUTHORIZATION_ARN);
cognitoProvider.refresh();
HashMap<String, String> logins = new HashMap<String, String>();
logins.put("com.leversystems.devauth", cognitoProvider.getToken());
credentialsProvider.setLogins(logins);
credentialsProvider.refresh();
client = new CognitoSyncManager(getApplicationContext(),
IDENTITY_POOL_ID, Regions.US_EAST_1, credentialsProvider);
dataset = client.openOrCreateDataset("GameInfo");
synchronize();
}
private void wipeCognitoSyncData() {
client.wipeData();
dataset.delete();
synchronize();
}
private void addCognitoSyncData() {
dataset.put("playerName", "Muneeb");
dataset.put("currentLevel", "29");
dataset.put("highScore", "120345");
synchronize();
}
private void displayCogntioSyncData() {
synchronize();
playerName.setText(dataset.get("playerName"));
currentLevel.setText(dataset.get("currentLevel"));
highScore.setText(dataset.get("highScore"));
}
private void synchronize() {
dataset.synchronize(new SyncCallback() {
@Override
public boolean onConflict(Dataset arg0, List<SyncConflict> arg1) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onDatasetDeleted(Dataset arg0, String arg1) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onDatasetsMerged(Dataset arg0, List<String> arg1) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onFailure(DataStorageException arg0) {
System.err.println("Error onSyncro: " + arg0.getMessage());
}
@Override
public void onSuccess(Dataset arg0, List<Record> arg1) {
System.out.println("Dataset Synchronized!");
}
});
}
}
BYOIProvider 类
package com.leversystems.authserver;
import com.amazonaws.auth.AWSAbstractCognitoIdentityProvider;
public class BYOIProvider extends AWSAbstractCognitoIdentityProvider {
public static String id;
public static String token;
public BYOIProvider(String acctId, String identityPoolId) {
super(acctId, identityPoolId);
}
@Override
public String getProviderName() {
return "com.leversystems.devauth";
}
@Override
public String refresh() {
update(id, token);
return null;
}
}
工作流程
- 当单击按钮时,从 android App调用getCredentials()从 Java Server Class 获取令牌和 id。
- 然后将 Token 和 Id 传递给BYOIProvider 类以更新它们。
- 调用 syncData()来初始化 CognitoCredentialProvider 和 BYOIProvider 变量。
- CognitoSyncManager 使用 CognitoCredentialProvider 的对象进行初始化。
- 在此之后我收到一个异常错误
列 identity_id 和 dataset_name 不是唯一的
在这行代码上
数据集 = client.openOrCreateDataset("MyData");
更新 1(2014 年 11 月 11 日)
好的,我现在已将 refresh() 的返回字符串更改为令牌变量,这是堆栈跟踪。
11-11 12:58:52.196: I/View(29237): Touch down dispatch to android.widget.Button{4186d880 VFED..C. ........ 206,342-417,438 #7f080003 app:id/button1}, event = MotionEvent { action=ACTION_DOWN, id[0]=0, x[0]=76.0, y[0]=34.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=228482273, downTime=228482273, deviceId=2, source=0x1002 }
11-11 12:58:52.213: D/GraphicBuffer(29237): create handle(0x5ed83e60) (w:720, h:1280, f:1)
11-11 12:58:52.222: I/SurfaceTextureClient(29237): [STC::queueBuffer] (this:0x5d12eb78) fps:0.10, dur:20282.80, max:20162.90, min:119.90
11-11 12:58:52.222: I/SurfaceTextureClient(29237): [STC::queueBuffer] this:0x5d12eb78, api:1, last queue time elapsed:20162.90
11-11 12:58:52.326: I/View(29237): Touch up dispatch to android.widget.Button{4186d880 VFED..C. ...P.... 206,342-417,438 #7f080003 app:id/button1}, event = MotionEvent { action=ACTION_UP, id[0]=0, x[0]=76.0, y[0]=34.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=228482404, downTime=228482273, deviceId=2, source=0x1002 }
11-11 12:58:52.327: V/Provider/Settings(29237): from settings cache , name = sound_effects_enabled , value = 0
11-11 12:58:52.328: D/dalvikvm(29237): create interp thread : stack size=128KB
11-11 12:58:52.328: D/dalvikvm(29237): create new thread
11-11 12:58:52.328: D/dalvikvm(29237): new thread created
11-11 12:58:52.328: D/dalvikvm(29237): update thread list
11-11 12:58:52.329: D/dalvikvm(29237): threadid=15: interp stack at 0x60115000
11-11 12:58:52.329: D/dalvikvm(29237): threadid=15: created from interp
11-11 12:58:52.329: D/dalvikvm(29237): start new thread
11-11 12:58:52.329: D/dalvikvm(29237): threadid=15: notify debugger
11-11 12:58:52.329: D/dalvikvm(29237): threadid=15 (RefQueueWorker@org.apache.http.impl.conn.tsccm.ConnPoolByRoute@419852e8): calling run()
11-11 12:58:52.330: I/System.out(29237): httpget:http://192.168.1.112:8080/AuthenticationService/services/auth/gctbda
11-11 12:58:52.331: I/System.out(29237): http://192.168.1.112:8080/AuthenticationService/services/auth/gctbda
11-11 12:58:52.331: D/dalvikvm(29237): create interp thread : stack size=128KB
11-11 12:58:52.331: D/dalvikvm(29237): create new thread
11-11 12:58:52.332: D/dalvikvm(29237): new thread created
11-11 12:58:52.332: D/dalvikvm(29237): update thread list
11-11 12:58:52.332: D/dalvikvm(29237): threadid=16: interp stack at 0x60235000
11-11 12:58:52.332: D/dalvikvm(29237): threadid=16: created from interp
11-11 12:58:52.332: D/dalvikvm(29237): start new thread
11-11 12:58:52.333: D/dalvikvm(29237): threadid=16: notify debugger
11-11 12:58:52.333: D/dalvikvm(29237): threadid=16 (pool-3-thread-1): calling run()
11-11 12:58:52.336: I/System.out(29237): [socket][1] connection /192.168.1.112:8080;LocalPort=35830(10000)
11-11 12:58:52.336: I/System.out(29237): [CDS]connect[/192.168.1.112:8080] tm:10
11-11 12:58:52.336: D/Posix(29237): [Posix_connect Debug]Process com.leversystems.authserver :8080
11-11 12:58:52.358: I/System.out(29237): [socket][/192.168.1.136:35830] connected
11-11 12:58:52.358: I/System.out(29237): [CDS]rx timeout:10000
11-11 12:58:52.358: I/System.out(29237): [CDS]SO_SND_TIMEOUT:0
11-11 12:58:52.360: I/System.out(29237): >doSendRequest
11-11 12:58:52.361: I/System.out(29237): <doSendRequest
11-11 12:58:53.259: I/AmazonWebServiceClient(29237): {cognito-sync, us-east-1} was not found in region metadata, trying to construct an endpoint using the standard pattern for this region: 'cognito-sync.us-east-1.amazonaws.com'.
11-11 12:58:53.259: D/CognitoCachingCredentialsProvider(29237): Identity id is changed
11-11 12:58:53.259: D/CognitoCachingCredentialsProvider(29237): Saving identity id to SharedPreferences
11-11 12:58:53.260: I/CognitoSyncManager(29237): identity change detected
11-11 12:58:53.271: W/System.err(29237): Exception in OnSuccess: columns identity_id, dataset_name are not unique (code 19)
更新 2(2014 年 11 月 13 日)
添加
credentialsProvider.refresh();
在 setLogins()/withLogins() 之后
现在,如果我尝试使用错误的令牌,它会给出相应的异常。当我提供的令牌正确时,它会给我这个异常
Exception in onSuccess: Not authorized to perform sts:AssumeRoleWithWebIdentity (Service: AWSSecurityTokenService; Status Code: 403; Error Code: AccessDenied; Request ID: *SomeID*)
更新 3(2014 年 11 月 13 日)
好的,所以我在 IAM 控制台上创建了一个新角色。Update-2中的异常现在很清楚了。下一个问题与第一个问题相同。我在 AsyncHttpClient 中收到的确切异常是
11-13 15:40:41.738: I/AmazonWebServiceClient(23921): {cognito-sync, us-east-1} was not found in region metadata, trying to construct an endpoint using the standard pattern for this region: 'cognito-sync.us-east-1.amazonaws.com'.
11-13 15:40:41.739: D/CognitoCachingCredentialsProvider(23921): Identity id is changed
11-13 15:40:41.739: D/CognitoCachingCredentialsProvider(23921): Saving identity id to SharedPreferences
11-13 15:40:41.740: I/CognitoSyncManager(23921): identity change detected
11-13 15:40:41.749: W/System.err(23921): Exception in OnSuccess: columns identity_id, dataset_name are not unique (code 19)
更新 4 (14/11/2014)
我更新的代码和 StackTrace
代码:
credentialsProvider = new CognitoCachingCredentialsProvider(
getApplicationContext(), cognitoProvider, null,
AUTHORIZATION_ARN);
cognitoProvider.refresh();
堆栈跟踪:
11-14 11:25:01.357: I/AmazonWebServiceClient(31084): {cognito-sync, us-east-1} was not found in region metadata, trying to construct an endpoint using the standard pattern for this region: 'cognito-sync.us-east-1.amazonaws.com'.
11-14 11:25:01.358: D/CognitoCachingCredentialsProvider(31084): Identity id is changed
11-14 11:25:01.358: D/CognitoCachingCredentialsProvider(31084): Saving identity id to SharedPreferences
11-14 11:25:01.358: I/CognitoSyncManager(31084): identity change detected
11-14 11:25:01.367: W/System.err(31084): Exception in OnSuccess: columns identity_id, dataset_name, key are not unique (code 19)