3つのプロジェクトがあります1-Javascript SPA 2-Web APIプロジェクト、3-EF Coreを備えたIdentityServer
APIとIdentity Serverのデバッグを開始し、jwtトークンを正常に取得しましたが、Authorize属性を持つAPIメソッドから値を取得しようとすると、エラーが発生します。
WWW-Authenticate →Bearer error="invalid_token", error_description="The audience is invalid"
認証オプションでオーディエンスに関するプロパティが見つかりませんでした。これはAPIプロジェクトの私の構成です
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
ApiSecret="secret",
Authority = "http://localhost:5000",
ApiName="fso.Api",
RequireHttpsMetadata = false,
});
そして、IdentityのConfig.csファイル
public class Config
{
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource()
{
Name = "fso.Api",
DisplayName = "feasion API",
Scopes =
{
new Scope("api1"),
new Scope(StandardScopes.OfflineAccess)
},
UserClaims =
{
JwtClaimTypes.Subject,
JwtClaimTypes.EmailVerified,
JwtClaimTypes.Email,
JwtClaimTypes.Name,
JwtClaimTypes.FamilyName,
JwtClaimTypes.PhoneNumber,
JwtClaimTypes.PhoneNumberVerified,
JwtClaimTypes.PreferredUserName,
JwtClaimTypes.Profile,
JwtClaimTypes.Picture,
JwtClaimTypes.Locale,
JwtClaimTypes.IdentityProvider,
JwtClaimTypes.BirthDate,
JwtClaimTypes.AuthenticationTime
}
}
};
}
public static List<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Email(),
new IdentityResources.Profile(),
};
}
// client want to access resources (aka scopes)
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
ClientId = "fso.api",
AllowOfflineAccess=true,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
AllowedScopes =
{
StandardScopes.OfflineAccess,
"api1"
}
}
};
}
}
このクレームの内容については、 here を参照してください。
Aud(オーディエンス)クレームは、JWTが対象とする受信者を識別します。 JWTを処理することを意図した各プリンシパルは、オーディエンスクレームの値で自身を識別する必要があります。クレームを処理するプリンシパルが、このクレームが存在するときにaudクレームの値で自身を識別しない場合、JWTは拒否されなければなりません。
したがって、JWTがAPIのミドルウェアによって検証されたときに有効になるためには、APIの名前がaudクレームに存在する必要があります。 jwt.io を使用してトークンを確認することができます。これは、意味を理解するのに役立ちます。
IdentityServerにAPIの名前をaudクレームに追加させるには、クライアントコード(APIからリソースを取得しようとしているためアクセストークンが必要)がAPIにスコープを要求する必要があります。たとえば、次のような(MVCクライアントから):
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
Authority = Configuration["IdpAuthorityAddress"],
ClientId = "my_web_ui_id",
Scope = { "api1" },
//other properties removed...
});
エラーを回避するには、視聴者を一貫して4か所に追加する必要があります
1.カスタムスコープとしてのMy(e.g. MVC)クライアント.
2。 APIアプリケーションでApiNameとして
3.IdentityServer ClientsでAllowedScopeとして設定
4.ApiResourceとしてのAPIリソース設定
詳細を参照(IdentityServer4 wikiで以前入手可能):
IdentityServer4で新しいAPI接続を設定すると、エラーが発生する場合があります。
WWW-Authenticate: Bearer error="invalid_token",
error_description="The audience is invalid"
エラーを回避するには、オーディエンスを常に4か所に追加する必要があります
1.カスタムスコープとしてのMy(e.g. MVC)クライアント:
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
Authority = Configuration["IdpAuthorityAddress"],
ClientId = "my_web_ui_id",
Scope = { "openid", "profile", "offline_access", "MyApi" },
//other properties removed for brevity...
});
2. APIアプリケーションでApiNameとして
var identityServerAuthenticationOptions = new IdentityServerAuthenticationOptions()//Microsoft.AspNetCore.Builder.IdentityServerAuthenticationOptions
{
Authority = Configuration["Authentication:IdentityServer:Authority"],
RequireHttpsMetadata = false,
EnableCaching = false,
ApiName = "MyApi",
ApiSecret = "MyApiSecret"
};
IdentityServer\IdentityServerHost\Configuration\Clients.cs(またはデータベース内の対応するClientsエントリ)
var client = new Client
{
ClientId = clientId,
//other properties removed for brevity...
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
//IdentityServerConstants.StandardScopes.Email,
IdentityServerConstants.StandardScopes.OfflineAccess,
"MyApi",
},
};
4. IdentityServer\IdentityServerHost\Configuration\Resources.cs(またはデータベース内の対応するApiResourceエントリ)でapiResource.Scopesとして
var apiResource = new ApiResource
{
Name = "MyApi",
ApiSecrets =
{
new Secret("MyApiSecret".Sha256())
},
UserClaims =
{
JwtClaimTypes.Name,
JwtClaimTypes.Profile,
},
};