Я не могу понять это. Я смущен всем процессом аутентификации. Существует так много жаргона - токены, коды авторизации, идентификаторы, учетные записи, арендаторы, субъекты заявок, области действия, клиентские приложения, OWIN, OpenID, MSAL, ADAL, Azure, AD, Office365, Graph API и др. c. И это менялось несколько раз, так что шансы на то, что документация, на которую я смотрю, не относится даже к текущей версии!
Я рассмотрю свою текущую проблему, но я ищу некоторую общую помощь, так как хорошо. Для аутентификации сайта у меня есть некоторый код в моем классе запуска, который инициализирует аутентификацию для сайта:
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 отправляет обратно код авторизации, который обрабатывается здесь:
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]
. Я считаю, что все вышеперечисленное работает правильно. Я не совсем понимаю, что он делает, но я могу войти и просмотреть безопасные действия. У меня проблемы с доступом к API Graph в действии:
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. Но для этого требуется идентификатор, который из прочитанных мною учебников сказал, что я должен получать из ConfidentialClientApplication, как показано. Но в большинстве случаев я получаю ноль учетных записей при вызове GetAccountsAsyn c (). Раз или два я получил учетную запись, и все работало, но это очень прерывисто. Когда я смотрю на информацию об отладке, я получаю что-то вроде этого:
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