6

AspNet.Security.OpenIdConnect.Serverの例では、認証サーバーとリソースサーバーの両方に似ています。私はそれらを分離したいと思います。私はそうした。認証サーバのStartup.Configで認証サーバーとリソースサーバーをAspNet.Security.OpenIdConnectで区切る - 対象ユーザーですか?

、私は次の設定があります。

app.UseOpenIdConnectServer(options => { 

    options.AllowInsecureHttp = true; 
    options.ApplicationCanDisplayErrors = true; 
    options.AuthenticationScheme = OpenIdConnectDefaults.AuthenticationScheme; 
    options.Issuer = new System.Uri("http://localhost:61854"); // This auth server 
    options.Provider = new AuthorizationProvider(); 
    options.TokenEndpointPath = new PathString("/token");    
    options.UseCertificate(new X509Certificate2(env.ApplicationBasePath + "\\mycertificate.pfx","mycertificate")); 

}); 

私が書かれAuthorizationProviderを持っていますが、私はそれが私の現在の問題に関連してだと思う(しかし、おそらく関連)はありません。それはすべてのトークンの要求のために検証しているように、そのGrantResourceOwnerCredentialsオーバーライド、Iハードコードでクレームプリンシパル:リソースサーバで

public override Task GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsNotification context) 
{ 
    var identity = new ClaimsIdentity(OpenIdConnectDefaults.AuthenticationScheme); 

    identity.AddClaim(ClaimTypes.Name, "me"); 
    identity.AddClaim(ClaimTypes.Email, "[email protected]"); 
    var claimsPrincipal = new ClaimsPrincipal(identity); 

    context.Validated(claimsPrincipal); 
    return Task.FromResult<object>(null); 
} 

、私はそのStartup.configに次き:

app.UseWhen(context => context.Request.Path.StartsWithSegments(new PathString("/api")), branch => 
{ 
    branch.UseOAuthBearerAuthentication(options => { 
     options.Audience = "http://localhost:54408"; // This resource server, I believe. 
     options.Authority = "http://localhost:61854"; // The auth server 
     options.AutomaticAuthentication = true;    
    }); 
}); 

フィドラーで、私はトークンを求める、と私は1つを得る:

POST /token HTTP/1.1 
Host: localhost:61854 
Content-Type: application/x-www-form-urlencoded 

username=admin&password=aaa000&grant_type=password 

をだから今、私は、リソースサーバから保護されたリソースにアクセスするために、そのアクセストークンを使用します。

GET /api/values HTTP/1.1 
Host: localhost:54408 
Content-Type: application/json;charset=utf-8 
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI..... 

このエラーが発生する - オーディエンスの検証に失敗しました。視聴者:「空」。 validationParameters.ValidAudience: 'http://localhost:54408'またはvalidationParameters.ValidAudiences: 'null'と一致しませんでした。

は私が(app.UseOpenIdConnectServer(...)で)認証サーバで聴衆を設定することはありませんので、理由が理由だと思うので、私はそれがトークンへの視聴者の情報を書いたとは思いません。ですから、私は認証サーバーで(IdentityServer3で行われているように)オーディエンスを設定する必要がありますが、私はそれを可能にするオプションオブジェクトのプロパティを見つけることができません。

AspNet.Security.OpenIdConnect.Serverはauthとリソースが同じサーバーに存在する必要がありますか?

ClaimsPrincipalをまとめるときに視聴者を設定していますか?

カスタムオーディエンスバリデータを作成してシステムに接続する必要がありますか? (これに対する答えがいいえであることを願っています)

答えて

5

AspNet.Security.OpenIdConnect.Serverはauthとリソースが同じサーバーに存在する必要がありますか?

もちろん、2つの役割を分離することはできます。

明示的に指定していない場合、認証サーバーは、アクセストークンの宛先/オーディエンスを特定する方法がありません。これは、デフォルトではaudのクレームなしで発行されます。 OAuth2ベアラミドルウェア。この問題を解決する

は簡単です:認証チケットを作成するときだけticket.SetResources(resources)を呼び出し、認証サーバは、それがaud請求(複数可)に追加する必要がありますどの値(S)(すなわち、リソースサーバ/ API)を正確に知ることができます。

app.UseOpenIdConnectServer(options => 
{ 
    // Force the OpenID Connect server middleware to use JWT tokens 
    // instead of the default opaque/encrypted token format used by default. 
    options.AccessTokenHandler = new JwtSecurityTokenHandler(); 
}); 

public override Task HandleTokenRequest(HandleTokenRequestContext context) 
{ 
    if (context.Request.IsPasswordGrantType()) 
    { 
     var identity = new ClaimsIdentity(context.Options.AuthenticationScheme); 
     identity.AddClaim(OpenIdConnectConstants.Claims.Subject, "unique identifier"); 

     var ticket = new AuthenticationTicket(
      new ClaimsPrincipal(identity), 
      new AuthenticationProperties(), 
      context.Options.AuthenticationScheme); 

     // Call SetResources with the list of resource servers 
     // the access token should be issued for. 
     ticket.SetResources("resource_server_1"); 

     // Call SetScopes with the list of scopes you want to grant. 
     ticket.SetScopes("profile", "offline_access"); 

     context.Validate(ticket); 
    } 

    return Task.FromResult(0); 
}  

app.UseJwtBearerAuthentication(new JwtBearerOptions 
{ 
    AutomaticAuthenticate = true, 
    AutomaticChallenge = true, 
    Audience = "resource_server_1", 
    Authority = "http://localhost:61854" 
}); 
+0

ありがとうございました!それは今働きます!複数のユーザーがアクセストークンをリクエストできるようにするため、オプション1を使用しました。 –

+0

@MickaelCaruso 'ticket.SetResources'を使用するための私の答えを更新しました。' resource'パラメータは次回のベータ版でネイティブにサポートされなくなりました(https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnectを参照)。詳細については、Server/Issues/186を参照してください)。また、アクセストークンのデフォルトフォーマットとしてJWTの使用を中止します。https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/issues/186 – Pinpoint

+0

ありがとうございました。本当に助けてくれました。私のGrantResourceOwnerCredentialsメソッドはほぼ同じですが、私も identity.AddClaim(ClaimTypes.Name、 "MyFullName");を追加しました。 しかし、Web APIコントローラでUser.GetUserName()を呼び出すと、NULLが返されますか? User.GetUserId()は、NameIdentifierクレームで渡されるものを返します。 User.GetUserNameにデータを返すにはどうすればよいですか? – partyelite

関連する問題