ADAL 承载令牌不是 return 用户名而是 aad 客户端 ID
ADAL bearer token does not return username but aad client id
我们有一个使用 adal 来验证用户身份的桌面应用程序,使用此代码:
AuthenticationResult result = null;
var context = new AuthenticationContext(aadTenantDomain);
result = await context.AcquireTokenAsync(resourceId, clientId, returnUrl, new PlatformParameters(PromptBehavior.Auto));
这工作正常,返回的 AuthenticationResult 具有所有正确的用户信息。现在我们使用从 AuthenticationResult 获得的访问令牌调用托管在 azure 上的网络应用程序网络 api 控制器:
var Client = new HttpClient();
Client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", result.AccessToken);
这也正确地授权了用户。现在在 Web 控制器中,我们使用 User.Identity.Name 来获取由访问令牌授权的用户名。在昨天之前的好几个月里,这都运行良好,但今天 User.Identity.Name returns 桌面应用程序的客户端 ID 而不是用户名。有人知道哪里出了问题吗?
这是 api 身份验证配置:
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
PostLogoutRedirectUri = postLogoutRedirectUri,
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
{
RoleClaimType = System.Security.Claims.ClaimTypes.Role,
}
});
}
这是一个示例控制器函数:
[Authorize]
public class dialplanController : ApiController
{
public async Task<IHttpActionResult> GetMe()
{
var Me = db.dialplan.FirstOrDefault(d => d.email == User.Identity.Name);
return Ok(Me);
}
}
如果您希望 Web 应用同时支持 OpenIdConnection 和 Windows Azure Active Directory 承载令牌,您需要添加代码 app.UseWindowsAzureActiveDirectoryBearerAuthentication()
,如 juunas 所述。
例如,这里是供您参考的代码:
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = Authority,
PostLogoutRedirectUri = redirectUri,
RedirectUri = redirectUri,
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 = OnAuthorizationCodeReceived,
AuthenticationFailed = OnAuthenticationFailed,
RedirectToIdentityProvider= OnRedirectToIdentityProvider,
MessageReceived= OnMessageReceived,
SecurityTokenReceived= OnSecurityTokenReceived,
},
});
app.UseWindowsAzureActiveDirectoryBearerAuthentication(new Microsoft.Owin.Security.ActiveDirectory.WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Audience = "",
Tenant = "",
});
}
之后我们可以使用从 Azure AD 获取的令牌调用 Web API。并且 Azure Active Directory OWIN 组件将根据 access_token.
中的 unique_name
声明从委托令牌转换 User.Identity.Name
请从 this site 解码访问令牌以查看是否需要 unique_name
。
使用 ClaimsPrincipal.Current?.FindFirst(ClaimTypes.Upn)?.Value returns 当前用户的正确 UPN 或者如果没有给出 upn 则为 null。
我们有一个使用 adal 来验证用户身份的桌面应用程序,使用此代码:
AuthenticationResult result = null;
var context = new AuthenticationContext(aadTenantDomain);
result = await context.AcquireTokenAsync(resourceId, clientId, returnUrl, new PlatformParameters(PromptBehavior.Auto));
这工作正常,返回的 AuthenticationResult 具有所有正确的用户信息。现在我们使用从 AuthenticationResult 获得的访问令牌调用托管在 azure 上的网络应用程序网络 api 控制器:
var Client = new HttpClient();
Client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", result.AccessToken);
这也正确地授权了用户。现在在 Web 控制器中,我们使用 User.Identity.Name 来获取由访问令牌授权的用户名。在昨天之前的好几个月里,这都运行良好,但今天 User.Identity.Name returns 桌面应用程序的客户端 ID 而不是用户名。有人知道哪里出了问题吗?
这是 api 身份验证配置:
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
PostLogoutRedirectUri = postLogoutRedirectUri,
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
{
RoleClaimType = System.Security.Claims.ClaimTypes.Role,
}
});
}
这是一个示例控制器函数:
[Authorize]
public class dialplanController : ApiController
{
public async Task<IHttpActionResult> GetMe()
{
var Me = db.dialplan.FirstOrDefault(d => d.email == User.Identity.Name);
return Ok(Me);
}
}
如果您希望 Web 应用同时支持 OpenIdConnection 和 Windows Azure Active Directory 承载令牌,您需要添加代码 app.UseWindowsAzureActiveDirectoryBearerAuthentication()
,如 juunas 所述。
例如,这里是供您参考的代码:
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = Authority,
PostLogoutRedirectUri = redirectUri,
RedirectUri = redirectUri,
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 = OnAuthorizationCodeReceived,
AuthenticationFailed = OnAuthenticationFailed,
RedirectToIdentityProvider= OnRedirectToIdentityProvider,
MessageReceived= OnMessageReceived,
SecurityTokenReceived= OnSecurityTokenReceived,
},
});
app.UseWindowsAzureActiveDirectoryBearerAuthentication(new Microsoft.Owin.Security.ActiveDirectory.WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Audience = "",
Tenant = "",
});
}
之后我们可以使用从 Azure AD 获取的令牌调用 Web API。并且 Azure Active Directory OWIN 组件将根据 access_token.
中的unique_name
声明从委托令牌转换 User.Identity.Name
请从 this site 解码访问令牌以查看是否需要 unique_name
。
使用 ClaimsPrincipal.Current?.FindFirst(ClaimTypes.Upn)?.Value returns 当前用户的正确 UPN 或者如果没有给出 upn 则为 null。