Цель: войти в систему Azure Пользователь AD на веб-интерфейсе с диалоговым окном входа в систему Microsoft. Добавить токен в бэкэнд-запрос. Проверьте токен на бэкэнде, чтобы убедиться, что только авторизованные пользователи могут получить доступ к коду. Сложная часть: проверить вручную, потому что это не единственная аутентификация на месте.
Мне удалось войти в систему и отправить токен, но при проверке я получаю ошибки вроде: IDX10511: Signature validation failed. Keys tried: ...
Вот что у меня пока что:
app.module.ts
@NgModule({
declarations: [
AppComponent,
RestrictedPageComponent
],
imports: [
HttpClientModule,
MsalModule.forRoot({
auth: {
clientId: '<CLIENT ID>',
}
}, {
consentScopes: [
'user.read',
'openid',
'profile',
],
protectedResourceMap: [
['https://localhost:44323/v1/login', ['user.read']], // frontend
['https://localhost:5001/api/Login', ['user.read']] // backend
]
}),
BrowserModule,
AppRoutingModule
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: MsalInterceptor,
multi: true
},
],
bootstrap: [AppComponent]
})
export class AppModule { }
login.component.ts
login() {
const loginRequest = { scopes: ['https://graph.microsoft.com/User.ReadWrite'] };
this.authService.loginPopup(loginRequest);
}
И это, кажется, работает просто отлично. Я могу войти через Microsoft, и MsalInterceptor добавляет токен-носитель в заголовок запроса бэкэнда.
Теперь на бэкэнде я просто хочу убедиться, что токен действителен и что пользователь аутентифицирован корректно.
private JwtSecurityToken Validate(string token)
{
var stsDiscoveryEndpoint = "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration";
// also tried "https://login.microsoftonline.com/<TENANT ID>/v2.0/.well-known/openid-configuration"
var openIdConnectConfigurationRetriever = new OpenIdConnectConfigurationRetriever();
var configManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint, openIdConnectConfigurationRetriever);
var config = configManager.GetConfigurationAsync().Result;
var validationParameters = new TokenValidationParameters
{
IssuerSigningKeys = config.SigningKeys,
// just for now
ValidateAudience = false,
ValidateIssuer = false,
ValidateLifetime = false
};
var tokenHandler = new JwtSecurityTokenHandler();
IdentityModelEventSource.ShowPII = true;
token = token.Replace("Bearer ", string.Empty); // weird - the token starts with "Bearer " and is not valid like this
var result = tokenHandler.ValidateToken(token, validationParameters, out var jwt);
return jwt as JwtSecurityToken;
}
При вызове tokenHandler.ValidateToken(...
я всегда получаю сообщение об ошибке типа IDX10511: Signature validation failed. Keys tried: ...
. Я больше не уверен, правильно ли я понял и использовал всю концепцию. Чем больше я читаю об использовании Azure токена на предъявителя и валидации, тем больше он меня смущает.
Я могу разобрать токен на http://jwt.io, но подпись всегда недействительна.
Может ли бэкэнд проверить токен без передачи какого-либо общего секрета или идентификатора клиента? Правильный ли это подход для начала?
edit: Я не уверен, использовал ли я правильные конечные точки для вызова внешнего и внутреннего интерфейса и какую роль играют разные конечные точки (например, с идентификатором арендатора или без него) , Было бы здорово, если бы кто-то мог объяснить.
BR Матиас