[英]Restrict access to my API Endpoint to Android App
I want to restrict my API endpoints access only to my android app, but without google_account/password. 我想将我的API端点访问权限限制为仅对我的Android应用程序访问,而没有google_account / password。 I've the choice of those methods : https://developers.google.com/accounts/docs/OAuth2
我可以选择这些方法: https : //developers.google.com/accounts/docs/OAuth2
For test, I succeeded to authenticate my android app to my API with this method: https://cloud.google.com/appengine/docs/python/endpoints/consume_android ==> This method allow you to authenticate your app with combo: 为了进行测试,我使用以下方法成功地将我的android应用认证为我的API: https : //cloud.google.com/appengine/docs/python/endpoints/consume_android ==>此方法允许您使用组合认证您的应用:
So if someone get my code (Decompiling apk) and modify my android code, they can't access to my API because SHA1 fingerprint of my app will change. 因此,如果有人获得了我的代码(反编译apk)并修改了我的android代码,则他们将无法访问我的API,因为我的应用程序的SHA1指纹会更改。 (I tested it, and it works =) ) This method works fine, but I don't want Google login/password for authentication..
(我对其进行了测试,并且它可以工作=))这种方法可以正常工作,但是我不希望使用Google登录名/密码进行身份验证。
So I tried this method: https://developers.google.com/accounts/docs/OAuth2ServiceAccount I successfully authenticate my android app, BUT, if my android code is modified by someone else(So the SHA1 changed), my android app can still connect to my API !! 所以我尝试了这种方法: https : //developers.google.com/accounts/docs/OAuth2ServiceAccount我成功地验证了我的Android应用程序,但如果别人修改了我的Android代码(因此SHA1更改了), 我的Android应用程序就可以仍然连接到我的API! So if someone get my package and decompile it, he'll changed freely code and successfully access to my API..
因此,如果有人获得了我的软件包并对其进行了反编译,那么他将自由更改代码并成功访问我的API。
Here is my API Code: 这是我的API代码:
@ApiMethod( name = "ListCampagnes", httpMethod = ApiMethod.HttpMethod.GET, path="list", clientIds = {CONSTANTES.ANDROID_CLIENT_ID, CONSTANTES.WEB_CLIENT_ID, CONSTANTES.SERVICE_CLIENT_ID, com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID}, audiences = {CONSTANTES.ANDROID_AUDIENCE})
public Collection<Campagne> getCampagnes(@Named("NumPortable")String NumPortable, User user) throws UnauthorizedException {
if (user == null) throw new UnauthorizedException("User is Not Valid");
return CampagneCRUD.getInstance().findCampagne(NumPortable);
}
Here is my android code: 这是我的android代码:
GoogleCredential credentialToAppengine;
try {
String p12Password = "notasecret";
KeyStore keystore = KeyStore.getInstance("PKCS12");
InputStream keyFileStream = getAssets().open("59ce5a08e110.p12");
keystore.load(keyFileStream, p12Password.toCharArray());
PrivateKey key = (PrivateKey)keystore.getKey("privatekey", p12Password.toCharArray());
credentialToAppengine = new GoogleCredential.Builder().setTransport(AndroidHttp.newCompatibleTransport()).setJsonFactory(new JacksonFactory()).setServiceAccountId("301991144702-3v9ikfp4lsmokee1utkucj35847eddvg@developer.gserviceaccount.com").setServiceAccountPrivateKey(key).setServiceAccountScopes(Collections.singleton("https://www.googleapis.com/auth/userinfo.email")).build();
} catch (GeneralSecurityException e) {
e.printStackTrace();
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
}
Do I try an other method for authenticate my android App ? 我是否可以尝试其他方法来验证我的android应用程序? Or did I missing something in my API code ?
还是我的API代码中缺少某些内容? Thanks a looot in advance,
预先感谢抢劫
Authenticate Android End point without Google User Account is just impossible ! 在没有Google用户帐户的情况下验证Android端点是不可能的! I tried every ways but still doesn't works !
我尽了一切努力,但还是行不通!
So here is my way to resolv this problem, without any user interaction (Maybe not the right but that works, and you've got strong authentication (SHA1 + Google Account)): 因此,这是我无需任何用户干预即可解决此问题的方法(也许不正确,但可行,并且您拥有强身份验证(SHA1 + Google帐户)):
HERE IS MY ANDROID CODE 这是我的ANDROID代码
Get and Build Valid Credential 获取并建立有效凭证
//Get all accounts from my Android Phone
String validGoogleAccount = null;
Pattern emailPattern = Patterns.EMAIL_ADDRESS; // API level 8+
Account[] accounts = AccountManager.get(context).getAccounts();
for (Account account : accounts) {
if (emailPattern.matcher(account.name).matches()) {
//Just store mail if countain gmail.com
if (account.name.toString().contains("gmail.com")&&account.type.toString().contains("com.google")){
validGoogleAccount=account.name.toString();
}
}
}
//Build Credential with valid google account
GoogleAccountCredential credential = GoogleAccountCredential.usingAudience(this,"server:client_id:301991144702-5qkqclsogd0b4fnkhrja7hppshrvp4kh.apps.googleusercontent.com");
credential.setSelectedAccountName(validGoogleAccount);
Use this credential for secure calls 使用此凭据进行安全呼叫
Campagneendpoint.Builder endpointBuilder = new Campagneendpoint.Builder(AndroidHttp.newCompatibleTransport(), new JacksonFactory(), credential);
HERE IS MY API BACKEND CODE: API Annotation 这是我的API后端代码: API注释
@Api(
scopes=CONSTANTES.EMAIL_SCOPE,
clientIds = {CONSTANTES.ANDROID_CLIENT_ID,
CONSTANTES.WEB_CLIENT_ID,
com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID},
audiences = {CONSTANTES.ANDROID_AUDIENCE},
name = "campagneendpoint",
version = "v1"
)
Method code: 方法代码:
public Collection<Campagne> getCampagnes(@Named("NumPortable")String NumPortable, User user) throws UnauthorizedException {
if (user == null) throw new UnauthorizedException("User is Not Valid");
return CampagneCRUD.getInstance().findCampagne(NumPortable);
}
For the moment, it only works on Android (I don't know how we gonna do on IOS..).. 目前,它仅适用于Android(我不知道我们将如何在IOS上做..)。
Hope It will help you ! 希望对您有帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.