403: запрещено при чтении почты из серверного приложения с помощью Microsoft Graph

Я разрабатываю серверное приложение для получения электронных писем из нашего Office 365, фильтрации электронных писем и хранения их в нашей базе данных без входа пользователя в систему. Здесь ссылка на мой предыдущий вопрос, если вы хотите увидеть некоторые подробности.

Есть следующие методы

@Test
    public void testGetAccessTokenDeamon() throws Exception {

        String tenant="f0245-fd24-r3s-be8a-7745gra60be3";
        String authority = "https://login.windows.net/"+tenant+"/oauth2/authorize";
        ExecutorService service=null;
        service= Executors.newFixedThreadPool(1);

        try{

            AuthenticationContext authenticationContext= new AuthenticationContext(authority,false,service);
            String certFile="/mycert.pfx";
            InputStream pkcs12Cert= new SharedFileInputStream(certFile);

            AsymmetricKeyCredential credential=AsymmetricKeyCredential.create("g564f4-e53c-45b7-938a-gt6445gy667",pkcs12Cert,"passwd");


            Future<AuthenticationResult> future=authenticationContext.acquireToken("https://graph.microsoft.com",credential,null);

            System.out.println("Token Received"+future.get().getAccessToken());
            String token = future.get().getAccessToken();

            HttpGet httpGet = new HttpGet("https://graph.microsoft.com/v1.0/users");

            httpGet.setHeader("Authorization", "Bearer "+token);


            GraphServices graphServices = new GraphServices();
            ResponseEntity<String> responseEntity;


            responseEntity = graphServices.getEmails(token);




            //HttpClient httpClient= HttpClients.createDefault();

            //HttpResponse response=httpClient.execute(httpGet);
            //HttpEntity entity=response.getEntity();

        }
        catch (MalformedURLException e){
            e.printStackTrace();

        }
        catch (Exception e){
            e.printStackTrace();
        }


    }

public ResponseEntity<String> getEmails(String accessToken) throws Exception
    {
        logger.info("In getEmails");

        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        HttpEntity<String> request;

        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
        headers.add(AuthorizationConstants.AUTHORIZATION, AuthorizationConstants.BEARER + " " + accessToken);
        request = new HttpEntity<String>(headers);

        ResponseEntity<String> response = restTemplate.exchange("https://graph.microsoft.com/v1.0/users/[email protected]/messages", HttpMethod.GET, request, String.class);
        return response;
    }

Если я попытаюсь использовать https://graph.microsoft.com/v1.0/users/ в restTemplate я получу список пользователей, но для конкретного пользователя приведенный выше код возвращает 403.

Не могли бы вы посоветовать мне, какие конечные точки использовать, чтобы мое приложение могло получать доступ к отдельным сообщениям без входа пользователя в систему? Я уже предоставил приложению все необходимые разрешения (разрешения делегата и приложения).

ОБНОВЛЕНИЕ: это то, что у меня появляется, когда я запускаю токен на http://jwt.calebb.net/ и не смог найти раздел scp / scope.

{
 typ: "JWT",
 alg: "RS256",
 x5t: "xxxxx_mfg5JKHrwLBbd_4s",
 kid: "xxxxx_mfg5JKHrwLBbd_4s"
}.
{
 aud: "https://graph.microsoft.com",
 iss: "https://sts.windows.net/f456fyu44-df44-d3t3-f342-66423er4323/",
 iat: 1473280446,
 nbf: 1473280446,
 exp: 1473284346,
 appid: "4fw423gh-er423-45b7-zd32-3fwer2343szd",
 appidacr: "2",
 e_exp: 10800,
 idp: "https://sts.windows.net/g0412253-aeb2-4a8a-ju76-8736272a3u7e3/",
 oid: "33dd3455-0195-4708-rt44-34552321ds32d2",
 sub: "33dd3455-0195-4708-813d-34552321ds32d2",
 tid: "33dd3455-ae23-r456-be8a-7737cf4321d2e3",
 ver: "1.0"
}.
[signature]

Вот разрешения, которые я дал (все разрешения на данный момент) для приложения.

Microsoft Graph - Разрешения приложения: 18 - Делегированные разрешения: 40 Windows Azure Active Directory - Разрешения приложения: 4 - Делегированные разрешения: 8 Office 365 Exchange Online - Разрешения приложения: 9 - Делегированные разрешения: 30


person WowBow    schedule 07.09.2016    source источник


Ответы (1)


Я уже предоставил приложению все необходимые разрешения (разрешения делегата и приложения).

Это, наверное, не так :). Обычно 403 запрещено означает, что ваш токен не имеет требуемой области (в заявлении scp) для API, который вы вызываете. Легкий способ узнать: возьмите токен в отладчике (это большая длинная строка base64), затем перейдите к http://jwt.calebb.net/ и вставьте его. Вы увидите, что он декодирован в веб-токен JSON. Найдите претензию roles:

roles: [
  "Calendars.Read",
  "Mail.Read",
  "Contacts.Read" 
],

Если у вас нет Mail.Read или Mail.ReadWrite, у вас не настроены необходимые разрешения.

person Jason Johnston    schedule 07.09.2016
comment
Раздела scp нет вообще. :( - person WowBow; 07.09.2016
comment
Я обновил свой вопрос, чтобы отразить его на текущем токене. - person WowBow; 07.09.2016
comment
Где мне настроить прицел, если он отличается от указанного выше? - person WowBow; 08.09.2016
comment
Вы согласились на заявку? Вам нужно перейти к - https: // login.microsoftonline.com/common/oauth2/authorize?response_type=code&client_id={0}&resource={1}&redirect_uri={2}&state=SomeState&prompt=admin_consent (Убедитесь, что вы заменили { 0}, {1} и {2}) - person Saca; 08.09.2016
comment
Я дал приложению и делегировать разрешение для приложения с помощью интерфейса управления Azure. - person WowBow; 08.09.2016
comment
Неподдерживаемое значение 'prompt', когда я использовал prompt = admin_consent - person WowBow; 08.09.2016
comment
Мое плохое, это на самом деле roles утверждение в токене приложения. Я думаю, у вас может быть проблема, потому что вы определяете разрешения как для приложения, так и для делегата, и я, кажется, припоминаю, что это вызывает проблему. Попробуйте удалить свои делегированные разрешения и получить новый токен. - person Jason Johnston; 08.09.2016
comment
@Saca: согласие не требуется, если он зарегистрировал приложение в клиенте, к которому имеет доступ. Фактически регистрация = согласие. То, что вы описываете, необходимо только в сценариях с несколькими арендаторами. - person Jason Johnston; 08.09.2016
comment
@JasonJohnston Я попытался удалить всех делегатов, но до сих пор не вижу заявленных ролей в токене (поскольку я вставил результат, полученный от jwt), кстати, полученный мной токен всегда является одним и тем же токеном. - person WowBow; 08.09.2016
comment
Единственное, о чем я могу думать, это то, что я видел проблемы с кешированием при добавлении / удалении настроенных разрешений при регистрации приложения, поэтому, возможно, он очистится и начнет работать. В противном случае может быть некоторая тонкая разница в том, как библиотека ADAL обрабатывает запрос токена. Было бы хорошо, если бы вы могли перехватить запрос / ответ по сети. Я посмотрю, сможем ли мы попросить кого-нибудь из ребят из ADAL взглянуть. - person Jason Johnston; 09.09.2016
comment
@JasonJohnston Еще раз спасибо за ответ. Несмотря на то, что я не мог видеть роли, мы обнаружили, что человек, создавший приложение в Azure AD, не имел полного доступа администратора. Я предполагаю, что это привело к тому, что приложение, созданное этим человеком, не имело доступа к отдельным электронным письмам. Когда у пользователя появился полный доступ администратора, я смог получить необходимые данные. Так что пока у нас все в порядке. Спасибо за вашу помощь. - person WowBow; 12.09.2016
comment
@JasonJohnston еще один связанный с этим вопрос. Я сделал следующий вызов GET graph.microsoft.com/v1.0/users/[email protected]/, чтобы получить доступ к непрочитанным сообщениям, и я получаю сообщение 404 not found. Не только это, но каждый раз, когда я отправляю данные с помощью $ filter, я получаю ту же ошибку. Так что $ filter работает только тогда, когда вы аутентифицированы каждым отдельным пользователем (например, outlook.office.com/api/v2.0/me/)? Я пытаюсь получить непрочитанные электронные письма для определенного пользователя, используя создаваемое мной пакетное задание. Я приветствую вашу помощь. - person WowBow; 19.09.2016
comment
Он должен работать. Я бы предложил задать здесь еще один вопрос, комментарии уже длинные :) - person Jason Johnston; 19.09.2016