首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MSIS9649:收到无效的OAuth请求。“assertion”参数值不是有效的访问令牌

MSIS9649:收到无效的OAuth请求。“assertion”参数值不是有效的访问令牌
EN

Stack Overflow用户
提问于 2017-05-09 18:31:56
回答 1查看 797关注 0票数 0

我正在尝试实现ADFS4 - OAuth (OpenID连接)来进行身份验证和webapp到webapi的通信。

我已经相应地配置了ADFS应用程序组,并使用webapp中的OpenIdconnectauth管道进行身份验证。为了调用webapi,如果我仅使用客户端凭据授权来请求accesstoken,那么它工作得很好,因为我收到了有效的访问令牌,并且能够访问api。但是,访问令牌中没有任何我需要从webapi端获得的用户详细信息。

因此,我尝试从bootstrapcontext.token创建UserAssertion对象。但这一次,每当我请求访问令牌时,我都会收到标题中提到的这个错误。

以下是代码片段:

代码语言:javascript
复制
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中:

代码语言:javascript
复制
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中:

代码语言:javascript
复制
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的令牌是不正确的。但是我该如何解决这个问题呢?是否有其他方法可以将用户详细信息添加到访问令牌中。如果有人能帮助我们解决这个问题,我真的很感激?

谢谢。

EN

回答 1

Stack Overflow用户

发布于 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事件

代码语言:javascript
复制
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);
           }
       }

当您准备好进行呼叫时,您将以静默方式获取令牌。

代码语言:javascript
复制
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);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43867426

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档