简体   繁体   English

限制对Android App的API端点访问

[英]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 ==>此方法允许您使用组合认证您的应用:

  • Login/password (Google account) 登录名/密码(Google帐户)
  • SHA1 and package name of your android APP SHA1和您的Android APP的软件包名称

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM