aBl*_*aze 4 c# asp.net-mvc azure-active-directory adal microsoft-graph-api
我的 Startup.Auth.cs 如下所示:
public partial class Startup
{
private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
private static string appKey = ConfigurationManager.AppSettings["ida:ClientSecret"];
private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
private static string tenantId = ConfigurationManager.AppSettings["ida:TenantId"];
private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
public static readonly string Authority = aadInstance + tenantId;
// This is the resource ID of the AAD Graph API. We'll need this to request a token to call the Graph API.
string graphResourceId = "https://graph.microsoft.com";
public void ConfigureAuth(IAppBuilder app)
{
ApplicationDbContext db = new ApplicationDbContext();
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = Authority,
PostLogoutRedirectUri = postLogoutRedirectUri,
Notifications = new OpenIdConnectAuthenticationNotifications()
{
// If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away.
AuthorizationCodeReceived = (context) =>
{
var code = context.Code;
ClientCredential credential = new ClientCredential(clientId, appKey);
string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
TokenCache userTokenCache = new ADALTokenCache(signedInUserID);
AuthenticationContext authContext = new AuthenticationContext(Authority, userTokenCache);
AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceId);
string token = result.AccessToken;
return Task.FromResult(0);
}
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
上面的倒数第二行代码(字符串变量“token”)正确包含当前登录用户的 AccessToken。后来,我的 Web 应用程序项目尝试实例化 Microsoft GraphClient 对象,如下所示:
GraphServiceClient graphClient = new GraphServiceClient(new AuthenticationController());
Run Code Online (Sandbox Code Playgroud)
当上面的代码被调用时,就会创建一个新的 AuthenticationController,如下所示:
public class AuthenticationController : IAuthenticationProvider
{
private string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
private string appKey = ConfigurationManager.AppSettings["ida:ClientSecret"];
private string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
public async Task AuthenticateRequestAsync(HttpRequestMessage request)
{
string signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
string tenantID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
// get a token for the Graph without triggering any user interaction (from the cache, via multi-resource refresh token, etc)
ClientCredential creds = new ClientCredential(clientId, appKey);
TokenCache tokenCache = new ADALTokenCache(signedInUserID);
// initialize AuthenticationContext with the token cache of the currently signed in user, as kept in the app's database
AuthenticationContext authenticationContext = new AuthenticationContext(aadInstance + tenantID, tokenCache);
AuthenticationResult authResult = await authenticationContext.AcquireTokenAsync("https://graph.microsoft.com/", creds);
request.Headers.Add("Authorization", "Bearer " + authResult.AccessToken);
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是上面的 AuthenticationController 代码检索与 Web 应用程序关联的 AccessToken,而不是当前登录的用户。我需要使用当前登录用户的 AccessToken(而不是 Web 应用程序)实例化 GraphClient。具体来说,我希望最后一行代码中的变量 authResult.AccessToken 包含当前登录用户的 AccessToken。有什么方法可以安全地将当前登录用户的令牌缓存保存在 Startup.Auth.cs 中,然后在 AuthenticationController 类中检索它?
如果您已经有一个令牌,您可以调用tellGraphServiceClient来简单地使用该令牌,而不是尝试再次获取一个令牌。这是使用以下DelegateAuthenticationProvider类完成的:
var graphserviceClient = new GraphServiceClient(
new DelegateAuthenticationProvider(
(requestMessage) =>
{
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
return Task.FromResult(0);
}));
Run Code Online (Sandbox Code Playgroud)
存储该令牌的位置取决于应用程序的类型和您的架构。对于 Web 应用程序,您可以将其存储在 Session 或 Cookie 中,对于本机应用程序,您可以将其存储在内存中。令牌的寿命很短,因此任何临时存储通常都是可以接受的。
| 归档时间: |
|
| 查看次数: |
6708 次 |
| 最近记录: |