简体   繁体   English

为 Azure 用户访问检索持久令牌

[英]Retrieving a persistent token for Azure user access

I'm working on a project where I need access to a users mailbox (similar to how the MS Flow mailbox connector works), this is fine for when the user is on the site as I can access their mailbox from the graph and the correct permissions request.我正在做一个项目,我需要访问用户邮箱(类似于 MS Flow 邮箱连接器的工作方式),当用户在网站上时这很好,因为我可以从图中访问他们的邮箱和正确的权限请求。 The problem I have is I need a web job to continually monitor that users mail folder after they've given permission.我遇到的问题是我需要一个 web 作业来在用户授予权限后继续监视该用户的邮件文件夹。 I know that I can use an Application request rather than a delegate request but I doubt my company will sign this off.我知道我可以使用申请请求而不是委托请求,但我怀疑我的公司是否会签署此协议。 Is there a way to persistently hold an azure token to access the user information after a user has left the site.. eg in a webjob?有没有办法在用户离开网站后持久持有 azure 令牌以访问用户信息......例如在网络作业中?

Edit编辑

Maybe I've misjudged this, the user authenticates in a web application against an Azure Application for the requested scope也许我误判了这一点,用户在 web 应用程序中针对请求的 scope 的 Azure 应用程序进行身份验证

let mailApp : PublicClientApplication = new PublicClientApplication(msalAppConfig);
      let mailUser = mailApp.getAllAccounts()[0];
      let accessTokenRequest = {
        scopes : [ "User.Read", "MailboxSettings.Read", "Mail.ReadWrite", "offline_access" ],
        account : mailUser,
      }
      mailApp.acquireTokenPopup(accessTokenRequest).then(accessTokenResponse => {
.....
}

This returns the correct response as authenticated.这将返回经过身份验证的正确响应。

I then want to use this users authentication in a Console App / Web Job, which I try to do with然后我想在控制台应用程序/Web 作业中使用此用户身份验证,我尝试使用它

var app = ConfidentialClientApplicationBuilder.Create(ClientId)
                                          .WithClientSecret(Secret)
                                          .WithAuthority(Authority, true)
                                          .WithTenantId(Tenant)
                                          .Build();

                System.Threading.Tasks.Task.Run(async () =>
                {
                    IAccount test = await app.GetAccountAsync(AccountId);
                }).Wait();

But the GetAccountAsync allways comes back as null?但是 GetAccountAsync 总是返回 null?

@juunas was correct that the tokens are refreshed as needed and to use the AcquireTokenOnBehalfOf function. He should be credited with the answer if possible? @juunas 是正确的,根据需要刷新令牌并使用 AcquireTokenOnBehalfOf function。如果可能的话,他应该得到答案吗?

With my code, the idToken returned can be used anywhere else to access the resources.使用我的代码,返回的 idToken 可以在其他任何地方使用来访问资源。 Since my backend WebJob is continuous, I can use the the stored token to access the resource and refresh the token on regular intervals before it expires.由于我的后端 WebJob 是连续的,我可以使用存储的令牌访问资源并在令牌过期前定期刷新令牌。

Angalar App:安加拉尔应用程序:

let mailApp : PublicClientApplication = new PublicClientApplication(msalAppConfig);
let mailUser = mailApp.getAllAccounts()[0];
let accessTokenRequest = {
    scopes : [ "User.Read", "MailboxSettings.Read", "Mail.ReadWrite", "offline_access" ],
    account : mailUser,
}
mailApp.acquireTokenPopup(accessTokenRequest).then(accessTokenResponse => {
    let token : string = accessTokenResponse.idToken;
}

On the backend, either in an API, webJob or Console:在后端,在 API、webJob 或控制台中:

var app = ConfidentialClientApplicationBuilder.Create(ClientId)
                                                      .WithClientSecret(Secret)
                                                      .WithAuthority(Authority, true)
                                                      .WithTenantId(Tenant)
                                                      .Build();
            
var authProvider = new DelegateAuthenticationProvider(async (request) => {
   // Use Microsoft.Identity.Client to retrieve token
   List<string> scopes = new List<string>() { "Mail.ReadWrite", "MailboxSettings.Read", "offline_access", "User.Read" };
   var assertion = new UserAssertion(YourPreviouslyStoredToken);
   var result = await app.AcquireTokenOnBehalfOf(scopes, assertion).ExecuteAsync();
            
   request.Headers.Authorization =
                                    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", result.AccessToken);
});
var graphClient = new GraphServiceClient(authProvider);
var users = graphClient.Me.MailFolders.Request().GetAsync().GetAwaiter().GetResult();

In the end I had to abandon using the ConfidentialClientApplicationBuilder, I still use PublicClientApplicationBuilder on the front end to get the users consent but then I handle everything else with the oauth2/v2.0/token rest services which returns and accepts refresh tokens.最后我不得不放弃使用 ConfidentialClientApplicationBuilder,我仍然在前端使用 PublicClientApplicationBuilder 来获得用户的同意,但随后我使用返回并接受刷新令牌的 oauth2/v2.0/token rest 服务处理其他所有事情。

That way I can ask the user for mailbox consent using PublicClientApplicationBuilder Access the user mailbox at any time using oauth2/v2.0/token这样我就可以使用 PublicClientApplicationBuilder 向用户征求邮箱同意 随时使用 oauth2/v2.0/token 访问用户邮箱

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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