簡體   English   中英

微軟outlook認證oAuth2.0

[英]Microsoft outlook authentication oAuth2.0

我們有一個守護程序應用程序,它建立 IMAP 連接以訪問用戶的郵箱。 之前我們使用的是使用 email ID 和密碼的普通身份驗證方法來建立 IMAP 連接。 現在微軟已經阻止了這種類型的身份驗證過程並引入了oAuth2.0。

我的問題是我能夠與租戶內的用戶建立 IMAP 連接。 但是我無法弄清楚如果我需要訪問不屬於我的租戶的用戶郵箱或需要訪問任何個人 outlook 帳戶的郵箱,該怎么做。

我試圖在我的環境中重現相同的內容並得到以下結果:

請注意,如果您想訪問不屬於您的租戶的用戶郵箱或需要訪問任何個人 outlook 帳戶的郵箱,那么您必須注冊一個Multi-Tenant Azure AD Application ,如下所示:

在此處輸入圖像描述

我創建了一個 Azure AD 多租戶應用程序並授予了API 權限

在此處輸入圖像描述

現在,我使用以下命令在 Exchange 中注冊了服務主體:**

Connect-ExchangeOnline -Organization TenantID

New-ServicePrincipal -AppId AppID -ServiceId ObjectID [-Organization OrganizationID]
Get-ServicePrincipal | fl

在此處輸入圖像描述

我授予服務主體訪問一個郵箱的權限

Add-MailboxPermission -Identity "USER@XXX.com" -User 
ServicePrincipal_ID> -AccessRights FullAccess

Test-ApplicationAccessPolicy -Identity "USER@XXX.com" -AppId AppID

在此處輸入圖像描述

我使用如下參數通過 Postman 為多租戶應用程序生成了訪問令牌

https://login.microsoftonline.com/common/oauth2/v2.0/token

client_id:5f3068f5-a920-4d6d-9742-XXXXXX
client_secret:ESJ8Q~ShJVdlY2MhKicyTEApGdtZh*******
scope:https://outlook.office365.com/.default
grant_type:client_credentials

在此處輸入圖像描述

要在JAVA中執行相同操作,您可以參考user3206771在此SO 線程中提供的以下示例代碼:

public String getAccessTokenByClientCredentialGrant()  {       
    String accessToken = null;
    String clientId = "CLIENTID";
    String secret = "CLIENTSECRET";
    String authority = "https://login.microsoftonline.com/common/oauth2/v2.0/token";
    String scope = "https://outlook.office365.com/.default";
    log.info("Client ID : "+clientId);
    log.info("Client Secret : "+secret);
    log.info("Auth Server: "+authority);
    log.info("Scope: "+scope);
        try {
              ConfidentialClientApplication app = ConfidentialClientApplication.builder(
                clientId,
              ClientCredentialFactory.createFromSecret(secret))
                .authority(authority)
                .build();   
  
        ClientCredentialParameters clientCredentialParam = ClientCredentialParameters.builder(
                Collections.singleton(scope))
                .build();
        
        CompletableFuture<IAuthenticationResult> future = app.acquireToken(clientCredentialParam);
        IAuthenticationResult result = future.get();
        accessToken = result.accessToken();
        
    } catch(Exception e) {
        log.error("Exception in acquiring token: "+e.getMessage());
        e.printStackTrace();
    }
    log.info("Access Token : "+accessToken);
    return accessToken;
}
public Store connect(String userEmailId, String oauth2AccessToken) throws Exception {
    String host = "outlook.office365.com";
    String port = "993";
    Store store = null;
     
    String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
    Properties props= new Properties();
    props.put("mail.imaps.ssl.enable", "true");
    props.put("mail.imaps.sasl.enable", "true");
    props.put("mail.imaps.port", port);
    props.put("mail.imaps.auth.mechanisms", "XOAUTH2");
    props.put("mail.imaps.sasl.mechanisms", "XOAUTH2");
    props.put("mail.imaps.auth.login.disable", "true");
    props.put("mail.imaps.auth.plain.disable", "true");
    props.setProperty("mail.imaps.socketFactory.class", SSL_FACTORY);
    props.setProperty("mail.imaps.socketFactory.fallback", "false");
    props.setProperty("mail.imaps.socketFactory.port", port);
    props.setProperty("mail.imaps.starttls.enable", "true");
    props.put("mail.debug", "true");
    props.put("mail.debug.auth", "true");
    Session session = Session.getInstance(props);
    session.setDebug(true);
    store = session.getStore("imaps");
    log.info("OAUTH2 IMAP trying to connect with system properties to Host:" + host + ", Port: "+ port
            + ", userEmailId: " + userEmailId+ ", AccessToken: " + oauth2AccessToken);
    try {
    
        store.connect(host, userEmailId, oauth2AccessToken);
        log.info("IMAP connected with system properties to Host:" + host + ", Port: "+ port
            + ", userEmailId: " + userEmailId+ ", AccessToken: " + oauth2AccessToken);
        if(store.isConnected()){
            log.info("Connection Established using imap protocol successfully !");      
        }
    } catch (Exception e) {
        log.error("Store.Connect failed with the errror: "+e.getMessage());
        StringWriter sw = new StringWriter();
        e.printStackTrace(new PrintWriter(sw));
        String exceptionAsString = sw.toString();
        log.error(exceptionAsString);
     
    }
    return store;
}
public void getEmailContents() throws Exception {
    Store store = null;
       String accessToken = getAccessTokenByClientCredentialGrant();
    String emailId = "<email which needs to be read>";
    try {
        store = connect(emailId, accessToken );
    } catch (Exception ex) {
        log.error("Exception in connecting to email " + ex.getMessage());
        ex.printStackTrace();
        }
   }

暫無
暫無

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

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