2017-05-09 20 views
0

我正在尝试将ADFS4-OAuth(OpenID连接)用于身份验证和webapp与webapi通信。MSIS9649:收到无效的OAuth请求。 'assertion'参数值不是有效的访问令牌

我相应地配置了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 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的令牌不正确。但我该如何解决这个问题?有没有其他方式可以将用户详细信息输入到访问令牌中?我真的很感激有人能帮助我们解决这个问题吗?

谢谢。

回答

1

您必须使用授权代码流才能让MVC应用程序与API通话。 Vittorio has a nice post on it here, although it talks about azure.

为了做到这一点,你需要通过声明来处理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); 
相关问题