簡體   English   中英

使用 oauth2.0 的 EWS 現代身份驗證:遠程服務器返回錯誤:(401)Unauthorized

[英]EWS modern authentication using oauth2.0 : The remote server returned an error: (401)Unauthorized

我正在嘗試使用 Microsoft 圖形訪問令牌對 outlook 郵箱(用於從應用程序發送郵件)進行現代身份驗證。 我成功地從下面的代碼中獲取了訪問令牌:

   public class AuthTokenAccess {

public AuthTokenAccess() {}

public static String getAccessToken(String tenantId, String clientId, String clientSecret, String scope)
         {
    String endpoint = String.format("https://login.microsoftonline.com/%s/oauth2/token", tenantId);
    String postBody = String.format("grant_type=client_credentials&client_id=%s&client_secret=%s&resource=%s&scope=%s",
            clientId, clientSecret, "https://management.azure.com/", scope);
    String accessToken = null;
    try{
        HttpURLConnection conn = (HttpURLConnection) new URL(endpoint).openConnection();
    
    
        conn.setRequestMethod("POST");
    
    conn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    conn.setDoOutput(true);
    conn.getOutputStream().write(postBody.getBytes());
    conn.connect();
    JsonFactory factory = new JsonFactory();
    JsonParser parser = factory.createParser(conn.getInputStream());
    //String accessToken = null;
    while (parser.nextToken() != JsonToken.END_OBJECT) {
        String name = parser.getCurrentName();
        if ("access_token".equals(name)) {
            parser.nextToken();
            accessToken = parser.getText();
        }
    }
    }catch(Exception e) {
        
        
    }
    return accessToken;
}

獲得訪問令牌后,我將其發送到 ExchangeService:

  public ExchangeService getExchangeServiceObj(String emailId, String token, String emailServerURI) throws URISyntaxException {

    ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
        
        if(service != null) {
            service.getHttpHeaders().put("Authorization", "Bearer " + token);
            service.getHttpHeaders().put("X-AnchorMailbox", emailId);
            service.setUrl(new URI(emailServerURI));   //https://outlook.office365.com/EWS/Exchange.asmx
        }
    
    LOGGER.debug("getExchangeServiceObj() {}.", "ends");
    return service;
}

在這里,我得到 ExchangeService object 但是當我嘗試發送郵件時microsoft.exchange.webservices.data.core.service.item.EmailMessage.sendAndSaveCopy() 拋出異常

  public void sendMail(String toMail, String ccMail, String subject, String body, String pathOfFileToAttach) {

        ExchangeService emailService = getExchangeServiceObj(
                ResourceUtils.getPropertyValue("email_user"), 
                token, 
                ResourceUtils.getPropertyValue("ews_server"));

        if(!StringUtils.hasText(toMail)) { 
            toMail = ccMail;
        }
        EmailMessage emessage = new EmailMessage(emailService);
        
        emessage.setSubject(subject);
        String strBodyMessage = body;
        strBodyMessage = strBodyMessage + "<br /><br />";
        LOGGER.info("Body: {} ", body);
        MessageBody msg = new MessageBody(BodyType.HTML, strBodyMessage);
        emessage.setBody(msg);
        
        emessage.sendAndSaveCopy();
        LOGGER.info("Email send {}", "sucessfully");
    } catch(Exception e) {
        LOGGER.error(Constants.ERROR_STACK_TRACE, e);
        throw new CommonException(e);
    }
}

嘗試使用以下范圍: “https://outlook.office.com/EWS.AccessAsUser.All”“https://graph.microsoft.com/.default”

以下是我使用上述代碼獲得的訪問令牌:

{“aud”:“https://management.azure.com/”,“iss”:“https://sts.windows.net/3863b7d0-213d-40f3-a4d0-6cd90452245a/”,“iat”:1628068305 ,“nbf”:1628068305,“exp”:1628072205,“aio”:“E2ZgYEjcvsaipUV1wxwxrne/9F4XAAA=”,“appid”:“055eb578-4716-4901-861b-92f2469dac9c”,“appidacr”:“1”,“idp” ": "https://sts.windows.net/3863b7d0-213d-40f3-a4d0-6cd90452245a/", "oid": "33688cee-e16e-4d11-8ae0-a804805ea007", "rh": "0.AUYA0LdjOD0h80Ck0GkaZBFIkWR8Fni1XgU ", "sub": "33688cee-e16e-4d11-8ae0-a804805ea007", "tid": "3863b7d0-213d-40f3-a4d0-6cd90452245a", "uti": "nZUVod_e3EuO_T-Ter-_AQ", "ver": “1.0”,“xms_tcdt”:1626687774}

如您所見,令牌中不包含 scope。 獲取令牌時是否需要傳遞任何其他內容。

Azure 活動目錄設置:

  1. 注冊應用程序 2.創建客戶端密碼 3.添加重定向 URL 在此處輸入圖像描述

  2. 添加權限在此處輸入圖像描述

有人可以在這里幫助我嗎,我在哪里做錯了,或者是其他任何使它工作的方法。 謝謝

我首先可以在這里看到一些問題,您使用客戶端憑據流程,這需要您分配應用程序權限並且您只有委托權限,對於 EWS,唯一可以使用的應用程序權限是 full_access_as_app 請參閱https://learn.microsoft.com/ en-us/exchange/client-developer/exchange-web-services/how-to-authenticate-an-ews-application-by-using-oauth (僅限應用部分)

String endpoint = String.format("https://login.microsoftonline.com/%s/oauth2/token", tenantId);
String postBody = String.format("grant_type=client_credentials&client_id=%s&client_secret=%s&resource=%s&scope=%s",
        clientId, clientSecret, "https://management.azure.com/", scope);

您的混合 V1 和 V2 身份驗證(請參閱https://nicolgit.github.io/AzureAD-Endopoint-V1-vs-V2-comparison/ )在這里對於 v1 端點不起作用(范圍將被忽略)例如什么您在https://login.microsoftonline.com/%s/oauth2/token中擁有 V1 身份驗證端點,因此您的請求不應僅包含 scope 資源,該資源應為https://outlook.office.com

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM