MSIS9649:收到无效的OAuth请求。 该“声明”的参数值是不是有效的访问令牌(MSIS9

2019-11-04 09:09发布

我想实现ADFS4 - OAuth的(ID连接)进行身份验证和Web应用程序到的WebAPI通信。

我已经配置相应ADFS的应用程序组,并使用OpenIdconnectauth管道在Web应用程序进行身份验证。 为了通话的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 APP)看起来像两个Web应用和的WebAPI:

在Web应用程序:

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不正确。 但是,我怎么能解决这个问题? 有没有我可以得到的访问令牌的用户的详细信息任何其他方式。 我很感激,如果有人能帮助我们解决这个问题?

谢谢。

Answer 1:

你必须使用授权码流,以获得MVC应用程序交谈的API。 维托里奥上有一个很好的文章在这里,虽然它谈论蔚蓝。

为了做到这一点,你需要处理通过通知的AuthorizationCodeReceived事件的OpenIdConnectAuthenticationOptions从Startup.ConfigureAuth(IAppBuilder APP)

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);


文章来源: MSIS9649: Received invalid OAuth request. The 'assertion' parameter value is not a valid access token