我正在尝试实现ADFS4 - OAuth (OpenID连接)来进行身份验证和webapp到webapi的通信。
我已经相应地配置了ADFS应用程序组,并使用webapp中的OpenIdconnectauth管道进行身份验证。为了调用webapi,如果我仅使用客户端凭据授权来请求accesstoken,那么它工作得很好,因为我收到了有效的访问令牌,并且能够访问api。但是,访问令牌中没有任何我需要从webapi端获得的用户详细信息。
因此,我尝试从bootstrapcontext.token创建UserAssertion对象。但这一次,每当我请求访问令牌时,我都会收到标题中提到的这个错误。
以下是代码片段:
AuthenticationContext authContext = null;
AuthenticationResult result = null;
authContext = new AuthenticationContext(Startup.authority, false);
ClientCredential credential = new ClientCredential(Startup.clientId, Startup.appKey);
string usercheck = User.Identity.Name; //For checking, returns username
var bootstrapContext = ClaimsPrincipal.Current.Identities.First().BootstrapContext as System.IdentityModel.Tokens.BootstrapContext;
string username = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn) != null ? ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn).Value : ClaimsPrincipal.Current.FindFirst(ClaimTypes.Email).Value;
string userAccessToken = bootstrapContext.Token;
UserAssertion userAssertion = new UserAssertion(bootstrapContext.Token, "urn:ietf:params:oauth:grant-type:jwt-bearer", username);
string accessToken = null;
HttpClient httpClient = new HttpClient();
try {
//result = authContext.AcquireTokenAsync(Startup.apiResourceId, credential).Result; // This works fine but no user details in the token
result = authContext.AcquireTokenAsync(Startup.apiResourceId, credential, userAssertion).Result;
}以下是Startup.ConfigureAuth(IAppBuilder应用程序)在webapp和webapi中的外观:
在webapp中:
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
AuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType,
MetadataAddress = metadataAddress,
PostLogoutRedirectUri = postLogoutRedirectUri,
RedirectUri = postLogoutRedirectUri,
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters()
{
SaveSigninToken = true
},
ResponseType = "code id_token",
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = context =>
{
context.HandleResponse();
context.Response.Redirect("/Error?message=" + context.Exception.Message);
return Task.FromResult(0);
}
}
});
}在webapi中:
public void ConfigureAuth(IAppBuilder app)
{
JwtSecurityTokenHandler.InboundClaimTypeMap.Clear();
app.UseActiveDirectoryFederationServicesBearerAuthentication(
new ActiveDirectoryFederationServicesBearerAuthenticationOptions
{
MetadataEndpoint = ConfigurationManager.AppSettings["ida:AdfsMetadataEndpoint"],
TokenValidationParameters = new TokenValidationParameters() {
SaveSigninToken = true,
ValidAudience = ConfigurationManager.AppSettings["ida:Audience"]
}
});
}我认为我传递给userassertion的令牌是不正确的。但是我该如何解决这个问题呢?是否有其他方法可以将用户详细信息添加到访问令牌中。如果有人能帮助我们解决这个问题,我真的很感激?
谢谢。
发布于 2017-11-08 01:09:31
您必须使用授权码流来使MVC应用程序与API对话。Vittorio has a nice post on it here, although it talks about azure.
为此,您需要通过Startup.ConfigureAuth(IAppBuilder应用程序)上的通知来处理AuthorizationCodeReceived事件
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions {
...
Notifications = new OpenIdConnectAuthenticationNotifications {
AuthorizationCodeReceived = async code => {
ClientCredential credential = new ClientCredential(Startup.clientId, Startup.appKey);
AuthenticationContext authContext = new AuthenticationContext(Startup.authority, false);
AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync(
code.Code,
new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)),
credential,
Startup.apiResourceId);
}
}当您准备好进行呼叫时,您将以静默方式获取令牌。
var authContext = new AuthenticationContext(Startup.authority, false);
var credential = new ClientCredential(Startup.clientId, Startup.appKey);
var claim = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
var userId = new UserIdentifier(claim, UserIdentifierType.UniqueId);
result = await authContext.AcquireTokenSilentAsync(
Startup.apiResourceId,
credential,
userId);
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Bearer",
result.AccessToken);https://stackoverflow.com/questions/43867426
复制相似问题