我正在使用MSAL获取ID令牌,然后用它来访问Web API应用程序。我有几个问题,我想知道是否有人可以帮助我理解发生了什么。MSAL和Azure AD:当我只想获取用户ID时,应传递哪些范围?
让我从客户端的身份验证过程开始。在这种情况下,我构建了一个Windows窗体应用程序,该应用程序使用以下代码来验证当前用户(即,为了获得用于在用户访问Web时验证用户的ID令牌API应用程序):
//constructor code
_clientApp = new PublicClientApplication(ClientId,
Authority, //which url here?
TokenCacheHelper.GetUserCache());
_scopes = new []{ "user.read" }; //what to put here?
//inside a helper method
try {
return await _clientApp.AcquireTokenSilentAsync(_scopes, _clientApp.Users.FirstOrDefault());
}
catch (MsalUiRequiredException ex) {
try {
return await _clientApp.AcquireTokenAsync(_scopes);
}
catch (MsalException ex) {
return null;
}
}
我想清除的第一件事是应该用于权限参数的值。在这种情况下,我使用窗体上的网址:
https://login.microsoftonline.com/{Tenant}/oauth2/v2.0/token
不过,我的印象是,我也可以用这样的侥幸:
https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration
它似乎一个端点是特定于我的Azure AD,而另一个看起来像一般(全部捕获)URL ...我在哪里可以找到关于这些端点的更多信息以及每个端点的目的...
另一件事我无法把握的是范围。我对查询MS Graph(或任何其他Azure相关服务)并不感兴趣。在以前版本的MSAL库中,可以引用其中一个默认的作用域。但是,似乎这是不可能的(至少,我试过并得到一个异常,说我不应该通过默认范围......)。
传递一个空集合(例如:new List<string>()
)或null
也会导致错误。所以,在这种情况下,我已经结束了通过user.read
范围(如果我没有弄错的话,它被MS Graph API使用了。这显然不是必须的,但它是我设法获得身份验证的唯一方法当你只需要一个ID令牌时,如何进行呼叫的任何线索?我应该调用一个不同的方法吗?
移动到服务器端,我有一个Web API应用程序,它的访问权限是仅限于在认证头(承载)传递一个ID令牌调用根据这一sample,我应该使用这样的:现在
private void ConfigureAuth(IAppBuilder app) {
var authority = "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration";
app.UseOAuthBearerAuthentication(
new OAuthBearerAuthenticationOptions {
AccessTokenFormat = new JwtFormat(GetTokenValidationParameters(),
new OpenIdConnectCachingSecurityTokenProvider(authority)),
Provider = new OAuthBearerAuthenticationProvider {
OnValidateIdentity = ValidateIdentity
}
});
}
,这样做的工作,它会返回401的所有请求其不要没有VA盖子ID令牌。有一个问题:有没有一种方法可以从票证的身份中指定用于识别用户名(控制器的User.Identity.Name
)的声明?在这种情况下,我已经结束处理OnValidateIdentity
为了做到这一点的代码看起来像这样:
private Task ValidateIdentity(OAuthValidateIdentityContext arg) {
//username not getting correctly filled
//so, i'm handling this event in order to set it up
//from the preferred_username claim
if (!arg.HasError && arg.IsValidated) {
var identity = arg.Ticket.Identity;
var username = identity.Claims.FirstOrDefault(c => c.Type == "preferred_username")?.Value ?? "";
if (!string.IsNullOrEmpty(username)) {
identity.AddClaim(new Claim(ClaimTypes.Name, username));
}
}
return Task.CompletedTask;
}
正如你所看到的,我在寻找从ID令牌preferred_username要求(这是由客户获得)并使用其值设置Name声明。有没有任何选项可以让我自动执行此操作?我在OAuthBearerAuthenticationMiddleware
的配置中错过了什么吗?
Hello Mohit。 1帮助。 2,不是真的。例如,其中一些范围是默认发送的,正如我所说的,您不能在范围集合中重复使用它们。关于3,我找到了一个答案:https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/f10a045459e7cb07548806561a47ecdb3471f5f6/src/Microsoft.IdentityModel.Tokens/TokenValidationParameters.cs#L413 –