IdentityServer启用引用令牌

时间:2017-09-29 14:23:31

标签: c# identityserver3

目前我们正在使用JWT令牌进行身份验证(有效),但我想使用引用令牌。 目前我们的配置是这样的:

public static class Config
{

    /// <summary>
    /// Configures identity server
    /// </summary>
    public static void ConfigureIdentityServer(this IAppBuilder app, CormarConfig config)
    {

        // Create our options
        var identityServerOptions = new IdentityServerOptions
        {
            SiteName = "Cormar API",
            SigningCertificate = LoadCertificate(),
            IssuerUri = "https://cormarapi-test.azurewebsites.net",

            // Not needed
            LoggingOptions = new LoggingOptions
            {
                EnableHttpLogging = true,
                EnableWebApiDiagnostics = true,
                EnableKatanaLogging = true,
                WebApiDiagnosticsIsVerbose = true
            },

            // In membory crap just to get going
            Factory = new IdentityServerServiceFactory().Configure(config),         

            // Disable when live
            EnableWelcomePage = true
        };

        // Setup our auth path
        app.Map("/identity", idsrvApp =>
        {
            idsrvApp.UseIdentityServer(identityServerOptions);
        });
    }


    /// <summary>
    /// Configures the identity server to use token authentication
    /// </summary>
    public static void ConfigureIdentityServerTokenAuthentication(this IAppBuilder app, HttpConfiguration config)
    {
        app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
        {
            Authority = "https://cormarapi-test.azurewebsites.net/identity",
            DelayLoadMetadata = true,
            ValidationMode = ValidationMode.Local,
            RequiredScopes = new[] { "api" },

            ClientId = "api",
            ClientSecret = "not_my_secret"
        });

        AntiForgeryConfig.UniqueClaimTypeIdentifier = IdentityServer3.Core.Constants.ClaimTypes.Subject;
        JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();
    }

    /// <summary>
    /// Loads the certificate
    /// </summary>
    /// <returns></returns>
    private static X509Certificate2 LoadCertificate()
    {
        var certPath = $"{ AppDomain.CurrentDomain.BaseDirectory }App_Data\\idsrv3test.pfx";
        var certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
        certStore.Open(OpenFlags.ReadOnly);
        var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, "3A1AFB6E1DC5C3F341E63651542C740DA4148866", false);
        certStore.Close();

        // If we are on azure, get the actual self signed certificate, otherwise return the test one
        return certCollection.Count > 0 ? certCollection[0] : new X509Certificate2(certPath, "idsrv3test");
    }

    /// <summary>
    /// Configure the identity service factory with custom services
    /// </summary>
    /// <returns></returns>
    private static IdentityServerServiceFactory Configure(this IdentityServerServiceFactory factory, CormarConfig config)
    {
        var serviceOptions = new EntityFrameworkServiceOptions { ConnectionString = config.SqlConnectionString };
        factory.RegisterOperationalServices(serviceOptions);
        factory.RegisterConfigurationServices(serviceOptions);

        factory.CorsPolicyService = new Registration<ICorsPolicyService>(new DefaultCorsPolicyService { AllowAll = true }); // Allow all domains to access authentication
        factory.Register(new Registration<DbContext>(dr => dr.ResolveFromAutofacOwinLifetimeScope<DbContext>()));
        factory.UserService = new Registration<IUserService>(dr => dr.ResolveFromAutofacOwinLifetimeScope<IUserService>());
        factory.ClientStore = new Registration<IClientStore>(dr => dr.ResolveFromAutofacOwinLifetimeScope<IClientStore>());
        factory.ScopeStore = new Registration<IScopeStore>(dr => dr.ResolveFromAutofacOwinLifetimeScope<IScopeStore>());

        return factory;
    }
}

如您所见,我已将 ClientId ClientSecret 添加到 IdentityServerBearerTokenAuthenticationOptions 。 如果我将我的客户端的 AccessTokenType 设置为引用并尝试获取引用令牌,那么它会起作用,我会收到如下响应:

"access_token": "631783604e9c35e6b401605fe4809075",
"expires_in": 3600,
"token_type": "Bearer"

但是,如果我然后尝试访问我的服务器上的资源,我会收到401未经授权的错误。 如果我换回JWT AccessTokenType ,我可以进行身份​​验证,然后无任何问题地访问我的资源。

作为一个注释,我已将 ClientSecret ScopeSecret 设置为相同的值,因此我希望它可以正常工作。

我忘了做某事吗?

1 个答案:

答案 0 :(得分:3)

使用引用令牌类型时,无法在本地验证令牌。由于它是非结构化数据,没有可经过数字验证的签名,因此您的API需要使用IdentityServer检查令牌。

要执行此操作,请将ValidationMode更改为ValidationMode.ValidationEndpointValidationMode.Both

来自文档:

  

ValidationMode可以设置为Local(仅限JWT),ValidationEndpoint(使用验证端点的JWT和引用令牌 - 以及本地JWT和使用验证端点引用令牌的默认值(默认为Both)。 - https://identityserver.github.io/Documentation/docsv2/consuming/options.html