2017-05-09 6 views
0

ADAP4 - 인증을위한 OAuth (OpenID 연결) 및 webapi 통신에 대한 webapp을 구현하려고합니다.MSIS9649 : OAuth 요청이 잘못되었습니다. 'assertion'매개 변수 값이 유효한 액세스 토큰이 아닙니다.

이에 따라 ADFS 응용 프로그램 그룹을 구성하고 인증을 위해 webapp에서 OpenIdconnectauth 파이프 라인을 사용합니다. webapi를 호출하기 위해, 클라이언트 자격증 명 허가를 사용하여 accesstoken을 요청하면 유효한 액세스 토큰을 받고 api에 연결할 수있게되어 제대로 작동합니다. 그러나 액세스 토큰에는 webapi 끝에서 필요한 사용자 세부 정보가 없습니다.

그렇다면 bootstrapcontext.token에서 UserAssertion 개체를 만들어 보았습니다. 하지만 이번에는 액세스 토큰을 요청할 때 제목에 언급 된대로이 오류가 표시됩니다. 웹 애플리케이션에서

:

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

다음
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 응용 프로그램)는 웹 애플리케이션과 webapi 모두 같은 모습입니다 : 여기

는 코드입니다 그리고 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와 통신하게하려면 인증 코드 흐름을 사용해야합니다. 당신이 전화를 할 준비가되면 당신은 Startup.ConfigureAuth (IAppBuilder 응용 프로그램)에서 OpenIdConnectAuthenticationOptions에 공지를 통해 AuthorizationCodeReceived 이벤트를 처리 할 필요가 그렇게하기 위해 Vittorio has a nice post on it here, although it talks about azure.

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