JWT-аутентификация из приложений для Android

Я новичок в разработке Android, и мне нужно позвонить на HTTP-сервер, чтобы загрузить изображение. Перед этим пользователь входит в систему с именем пользователя и паролем, и токен JWT возвращается вместе с идентификатором пользователя. В функции загрузки изображения мне нужно предоставить токен и идентификатор для сервера, чтобы принять изображение после проверки сеанса, и именно здесь я сталкиваюсь с проблемами.

Я не уверен, связана ли проблема с загрузкой изображения или с проверкой сеанса, хотя из сообщений об ошибках кажется, что это второй случай.

Функция следующая:

public String sendPostMult(String myurl, String token, List<ValuePair> params, Bitmap bm) throws Exception {

    try {

        HttpClient client = new DefaultHttpClient();

        HttpPost post = new HttpPost(myurl);
        post.addHeader("Authorization", "Token token=\"" + token + "\"");
        MultipartEntityBuilder postEntity = MultipartEntityBuilder.create();

        ByteArrayOutputStream bao = new ByteArrayOutputStream();

        bm.compress(Bitmap.CompressFormat.PNG, 90, bao);

        byte[] ba = bao.toByteArray();

        String ba1 = Base64.encodeToString(ba, Base64.DEFAULT);

        // File file = new File("Your File path on SD card");
        // postEntity.addPart("fileupload", new FileBody(file, "image/jpeg"));
        for (ValuePair param : params) {
            postEntity.addTextBody(param.getValue(), param.getName());
            Log.d(param.getValue(), param.getName());
        }

        postEntity.addTextBody("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer");


        postEntity.addTextBody("client_assertion", token);

        postEntity.addTextBody("picture", ba1);
        // Log.d("YY", getBytesFromBitmap(bm).toString());
        post.setEntity(postEntity.build());

        HttpResponse response = client.execute(post);

        int responseCode = response.getStatusLine().getStatusCode();


        BufferedReader reader = new BufferedReader(new InputStreamReader(
                response.getEntity().getContent(), "UTF-8"));

        String sResponse = reader.readLine();

        return sResponse;

    }catch(Exception e)
    {
        e.printStackTrace();
        return "ERROR";
    }
}

Приведены следующие ошибки (пожалуйста, взгляните на последнюю):

11-11 10:51:09.780  11762-12135/team13.foods I/APACHE HTTP (thCr=686) - NafHttpAuthStrategyDefault﹕ (thUse=686) NafHttpAuthStrategyDefault()

11-11 10:51:09.780  11762-12135/team13.foods I/APACHE HTTP (thCr=686) - KeeperManager﹕ (thUse=686) INITIALIZATION of shared resources

11-11 10:51:09.780  11762-12135/team13.foods I/APACHE HTTP (thCr=686) - AndroidContextProviderImpl﹕ (thUse=686)    currentActivityThread=android.app.ActivityThread@420899a8
11-11 10:51:09.830  11762-12135/team13.foods I/APACHE HTTP (thCr=686) - GbaSupportIndicatorRequestUpdaterDefault﹕ (thUse=686) GbaSupportIndicatorRequestUpdaterAbstract()   userHeaderPredefined=Apache-HttpClient/UNAVAILABLE (java 1.4)

11-11 10:51:09.940  11762-11769/team13.foods I/dalvikvm﹕ Total arena pages for JIT: 11
11-11 10:51:09.940  11762-11769/team13.foods I/dalvikvm﹕ Total arena pages for JIT: 12
11-11 10:51:09.940  11762-11769/team13.foods I/dalvikvm﹕ Total arena pages for JIT: 13
11-11 10:51:09.940  11762-11769/team13.foods I/dalvikvm﹕ Total arena pages for JIT: 14
11-11 10:51:09.950  11762-11769/team13.foods I/dalvikvm﹕ Total arena pages for JIT: 15

11-11 10:51:09.960  11762-12135/team13.foods D/dalvikvm﹕ DexOpt: couldn't find static field Lorg/apache/http/message/BasicHeaderValueParser;.INSTANCE

11-11 10:51:09.960  11762-12135/team13.foods W/dalvikvm﹕ VFY: unable to resolve static field 1921 (INSTANCE) in Lorg/apache/http/message/BasicHeaderValueParser;

11-11 10:51:09.960  11762-12135/team13.foods D/dalvikvm﹕ VFY: replacing opcode 0x62 at 0x001b

11-11 10:51:09.960  11762-12135/team13.foods D/dalvikvm﹕ DexOpt: couldn't find static field Lorg/apache/http/message/BasicHeaderValueFormatter;.INSTANCE

11-11 10:51:09.960  11762-12135/team13.foods W/dalvikvm﹕ VFY: unable to resolve static field 1915 (INSTANCE) in Lorg/apache/http/message/BasicHeaderValueFormatter;

11-11 10:51:09.960  11762-12135/team13.foods D/dalvikvm﹕ VFY: replacing opcode 0x62 at 0x0015
11-11 10:51:09.970  11762-12135/team13.foods D/name﹕ djt
11-11 10:51:09.970  11762-12135/team13.foods D/description﹕ test
11-11 10:51:09.970  11762-12135/team13.foods D/tags﹕ hft
11-11 10:51:09.970  11762-12135/team13.foods D/id﹕ 545a7b69ed2f9c0200dfc995
11-11 10:51:10.000  11762-12135/team13.foods D/dalvikvm﹕ GC_FOR_ALLOC freed 799K, 16% free 7878K/9336K, paused 27ms, total 27ms

11-11 10:51:10.020  11762-12135/team13.foods I/APACHE HTTP (thCr=686) - NafHttpAuthStrategyDefault﹕ (thUse=686)    cached value : gbaSupportIsPossible=null

11-11 10:51:10.020  11762-12135/team13.foods I/APACHE HTTP (thCr=686) - NafHttpAuthStrategyDefault﹕ (thUse=686)    The current context is NOT a context of GBA service.

11-11 10:51:10.020  11762-12135/team13.foods I/APACHE HTTP (thCr=686) - GbaSupportPermissionRequestCheckerImpl﹕ (thUse=686) isCurrentProcessRequestedGba()#finished   result=false

11-11 10:51:10.020  11762-12135/team13.foods I/APACHE HTTP (thCr=686) - GbaSupportPermissionRequestCheckerImpl﹕ (thUse=686) isCurrentProcessAllowedToUseGba()#started   result=false

11-11 10:51:10.020  11762-12135/team13.foods I/APACHE HTTP (thCr=686) - NafHttpAuthStrategyDefault﹕ (thUse=686)    The GBA permission wasn't requested for this process.

11-11 10:51:10.020  11762-12135/team13.foods I/APACHE HTTP (thCr=686) - NafHttpAuthStrategyDefault﹕ (thUse=686) It is impossible to support GBA now (many possible reasons: no Android Context, current client is GBA service, etc.), then it will be just usual HTTP.

11-11 10:51:10.020  11762-12135/team13.foods I/APACHE HTTP (thCr=686) - NafRequestExecutorWrapperRedirectionHandler﹕ (thUse=686)    It isn't GBA flow, redirection responses are not handled.

11-11 10:51:11.280  11762-12135/team13.foods W/DefaultRequestDirector﹕ Authentication error: Unable to respond to any of these challenges: {}

11-11 10:51:11.280  11762-12135/team13.foods I/APACHE HTTP (thCr=686) - NafHttpAuthStrategyDefault﹕ (thUse=686)    cached value : gbaSupportIsPossible=false

11-11 10:51:11.280  11762-11762/team13.foods I/System.out﹕ UnauthorizedError: jwt must be provided

Так что похоже, что это действительно ошибка jwt. Если я удалю

post.addHeader("Authorization", "Token token=\"" + token + "\"");

строка, ошибка говорит: Должен быть предоставлен заголовок авторизации.

Итак, мои вопросы:

1) Правилен ли заголовок авторизации? Или он должен быть в другом формате?

2) Как сдать JWT? Я получил токен в виде строки и решил, что это то, что мне нужно передать. Однако верно то, что когда я получил токен, он содержал несколько полей, которые я разобрал на разные строки, и токен был одним из них. Так что, может быть, я должен просто сохранить все это и отправить его целиком в поле утверждения клиента? Но тогда я все равно должен отправлять токен только в заголовке авторизации?

3) Хотя это немного не связано, может быть, я отправляю изображение в неправильном формате?

Большое вам спасибо за ваше время. Я очень ценю это!


person Oliver Hoffman    schedule 11.11.2014    source источник
comment
In case you are wondering what the JWT looks like: {token:eyJ0eXAiOiJKV1QiLCJhbGiOiJIUzI1NiJ9.eyJlbWFpbCI6Im9saUBvbGkuY29tIiwicGFzc3dvcmQiOiIkMmEkMDUkZEVpYmhRUzlNLlMwRW9wTU5XWndrLi5rR1VIMWNFUk9HaW1mMDRYcFpnQWdtSTBBbTFPRk8iLCJfaWQiOiI1NDVhN2I2OWVkMmY5YzAyMDBkZmM5OTUiLCJfX3YiOjB9.voPftTnS4Wfg_S6_87N6DUpBxCcu9S_dyJpUj_rsxlk,id:545a7b69ed2f9c0200dfc995}   -  person Oliver Hoffman    schedule 11.11.2014


Ответы (1)


Глядя на JWT, ваша проблема прямо здесь. Это не JWT-токен.

JWT состоит из трех частей: <header>.<claims/payload>.<signature>. Ваши содержат только <payload>.<signature>. Я подозреваю, что у вас есть JWS (веб-подпись JSON), а не JWT (веб-токен JSON).

Вы можете прочитать о формате в спецификациях: http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#ExampleJWT

Если вам нужно устранить неполадки с токенами, это полезный инструмент: http://kjur.github.io/jsjws/mobile/tool_jwt.html

Кроме того, отправка пароля в заявке, как вы, кажется обратным, даже если он зашифрован. JWT вместо отправки паролей каждой службе. Службы доверяют контенту, проверяя подпись.

person Magnus    schedule 21.04.2015