验证Web API(.Net框架)中的IdentityServer4令牌

时间:2019-09-10 11:00:45

标签: c# authentication asp.net-web-api openid identityserver4

我想在Web API(.Net Framework 4.7.1)中验证从IdentityServer生成的令牌。

到目前为止,这是我在Web API的Startup.cs中所做的

public void Configuration(IAppBuilder app)
{

    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationType = "Cookies"
    });

    app.UseOpenIdConnectAuthentication(
        new OpenIdConnectAuthenticationOptions
        {
            RequireHttpsMetadata = false,
            SignInAsAuthenticationType = "Cookies",
            Authority = "https://localhost:44380/",
            RedirectUri = "http://localhost:4200/auth-callback",
            ClientId = "angular",
            Scope = "api1",
            ResponseType = "code"
        });

}

它引发code challenge required错误。

由于设计限制,我将无法使用IdentityServer/IdentityServer3.AccessTokenValidation,而应该使用UseOpenIdConnectAuthentication来验证令牌。

修改 我能够使它在Web API Core中工作。这是我的Web API Core的Startup.cs。但不确定如何在Web API .Net Framework中执行此操作。我还尝试了使用以下配置的IdentityServer/IdentityServer3.AccessTokenValidation,但它抛出401错误

public void Configuration(IAppBuilder app)
{
    app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
    {
        Authority = "https://localhost:44380",
        RequiredScopes = new[] { "api1" }
    });
}

2 个答案:

答案 0 :(得分:2)

  

由于设计限制,我将无法使用IdentityServer / IdentityServer3.AccessTokenValidation,而应该使用UseOpenIdConnectAuthentication来验证令牌。

结论是完全错误的。 OpenIdConnectAuthentication用于交互式登录,而不用于承载令牌验证。您可以改用IdentityServer3.Contrib.AccessTokenValidation

我为您准备了repo作品,还为我自己准备了更多作品。目标是4.7.2。一切都是硬编码的,但是唯一的配置块在startup.cs

public void Configuration(IAppBuilder app)
{
    app.UseIdentityServerBearerTokenAuthentication(new 
    IdentityServerBearerTokenAuthenticationOptions
    {
        Authority = "https://demo.identityserver.io/",
        RequiredScopes = new[] { "api" }
    });
}

如您所见,我利用了公共Identityserver实例。

我用卷发 获取令牌:

curl -d "grant_type=client_credentials&client_id=client&client_secret=secret" https://demo.identityserver.io//connect/token

并调用我的API:

curl -v  -H "Accept: application/json" -H "Authorization: Bearer <The token is here>"  http://localhost/MVCBearerNuget/api/TestApi

答案是:

< HTTP/1.1 200 OK
< Cache-Control: no-cache
< Pragma: no-cache
< Content-Type: application/json; charset=utf-8
< Expires: -1
< Server: Microsoft-IIS/10.0
< X-AspNet-Version: 4.0.30319
< X-Powered-By: ASP.NET
< Date: Tue, 10 Sep 2019 17:37:08 GMT
< Content-Length: 19
<
["value1","value2"]* Connection #0 to host localhost left intact

另一种方法是自己构建中间件,但是我针对的是最新的,易于使用的并且肯定有效。

答案 1 :(得分:0)

我已经使用.NET Framework 4.6.1创建Web API,对于Identity Provider,我使用的是Identity Server 4(之前使用过Identity Server 3)。最初我确实遇到了问题,但是我想出了一种对我来说非常有效的解决方法。请注意,我正在使用ClientCredentials授权流程。

我正在使用相同的IdentityServer3.AccessTokenValidation库进行令牌验证。诀窍是针对自省端点。以下是我的配置。

这是Web API的配置,请注意,设置设置ValidationMode属性至关重要。

app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
        {
            Authority = ConfigurationManager.AppSettings["AuthServerURI"],
            RequiredScopes = new[] { "comp-read", "stats-read" },
            ClientId = "apiname",
            ClientSecret = "apisecret",
            ValidationMode = ValidationMode.ValidationEndpoint,
            EnableValidationResultCache = true
        });

这是在我的IDP中配置APIResource和Client的方式。

new ApiResource
            {
                Name = "apiname",
                DisplayName = "Web API",
                Description = "Access to Web API Services",
                ApiSecrets = new List<Secret> {new Secret("apisecret".Sha256())},
                Scopes = new List<Scope> {
                    new Scope("comp-read", "Read access to Comp Db API"),
                    new Scope("stats-read", "Read access to Stats API")
                }

这是配置客户端之一的方式。

new Client
            {
                ClientName = "name of the client",
                ClientId = "clientname",
                Enabled = true,
                AllowedGrantTypes = GrantTypes.ClientCredentials,
                ClientSecrets = new List<Secret> {
                    new Secret("secretforclient".Sha256())
                },
                AllowedScopes = new List<string>
                {
                    "stats-read"
                },
                AccessTokenLifetime = 1000
            }

希望这会有所帮助。谢谢。