我已经为此进行了数周的角力,但我似乎无法弄清楚。我对整个身份验证过程感到困惑。术语,令牌,身份验证代码,身份,帐户,租户,声明主体,作用域,客户端应用程序,OWIN,OpenID,MSAL,ADAL,Azure,AD,Office365,Graph API等都有很多术语。它已经更改了多次,因此,我正在查看的任何文档甚至都不适用于当前版本!
我将解决当前的问题,但我也非常感谢您提供的一些常规帮助。对于站点身份验证,我的Startup类中有一些代码可以初始化站点的身份验证:
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions { CookieManager = new SystemWebCookieManager() });
string authority = string.Format(CultureInfo.InvariantCulture, aadInstance, tenant);
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientID,
Authority = authority,
Notifications = new OpenIdConnectAuthenticationNotifications()
{
// when an auth code is received...
AuthorizationCodeReceived = OnAuthorizationCodeReceivedAsync,
AuthenticationFailed = (context) =>
{
context.HandleResponse();
return Task.FromResult(0);
}
}
});
[我认为这可以将用户发送出去以进行登录。然后(我认为?!)Microsoft会发回一个auth代码,在这里进行处理:
private async Task OnAuthorizationCodeReceivedAsync(AuthorizationCodeReceivedNotification notification)
{
var idClient = ConfidentialClientApplicationBuilder.Create(clientID)
.WithAuthority(AzureCloudInstance.AzurePublic, tenant)
.WithRedirectUri(notification.Request.Uri.AbsoluteUri)
.WithClientSecret(clientSecret)
.Build();
var signedInUser = new ClaimsPrincipal(notification.AuthenticationTicket.Identity);
var tokenStore = new MemoryTokenStore(idClient.UserTokenCache, HttpContext.Current, signedInUser);
try
{
string[] scopes = graphScopes.Split(' ');
var result = await idClient.AcquireTokenByAuthorizationCode(scopes, notification.Code).ExecuteAsync();
var graphClient = new GraphServiceClient(
new DelegateAuthenticationProvider(
async (requestMessage) => {
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
}));
// Grab and cache user details...
}
catch (Exception ex)
{
// Handle exception...
}
}
然后在我的控制器中,我用[Authorize]
装饰安全动作。我相信以上所有方法均能正常工作。我真的不知道它在做什么,但是我可以登录并查看安全操作。我遇到麻烦的地方是在操作内访问Graph API:
public async Task<GraphServiceClient> GetAuthenticatedClient()
{
var idClient = ConfidentialClientApplicationBuilder.Create(clientID)
.WithAuthority(AzureCloudInstance.AzurePublic, tenant)
.WithRedirectUri(HttpContext.Request.Url.AbsoluteUri)
.WithClientSecret(clientSecret)
.WithLogging(writeToLog, LogLevel.Verbose, true)
.Build();
var tokenStore = new MemoryTokenStore(idClient.UserTokenCache, HttpContext, ClaimsPrincipal.Current);
var accounts = await idClient.GetAccountsAsync();
var scopes = graphScopes.Split(' ');
var result = await idClient.AcquireTokenSilent(scopes, accounts.FirstOrDefault()).ExecuteAsync();
return new GraphServiceClient(
new DelegateAuthenticationProvider(
async (requestMessage) => {
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
}
)
);
}
我所做的基本上与站点身份验证相同,但是由于我没有身份验证代码,因此我尝试使用AcquireTokenSilent。但这需要一个身份,我从阅读的教程中得知,应该从机密客户应用程序中获取身份,如图所示。但是大多数时候,我在调用GetAccountsAsync()时得到零个帐户。一到两次,我就获得了帐户,并且一切正常,但这是断断续续的。当我查看调试信息时,会得到如下信息:
Tried to use network cache provider for login.microsoftonline.com. Success? False
Tried to use known metadata provider for login.microsoftonline.com. Success? True
在一个实例中,它在我调试时成功检索了该帐户,],>
Tried to use network cache provider for login.microsoftonline.com. Success? True
所以,是的。谁能帮我弄清楚我的问题是什么?我一直为此奋斗不已,而且截止日期临近。
我已经为此进行了数周的角力,但我似乎无法弄清楚。我对整个身份验证过程感到困惑。行话太多了-令牌,授权码,身份,帐户,租户,...
我建议使用基于OAuth的技术时,高于所有其他条件: