IdentityServer 启用引用令牌

IdentityServer enable reference tokens

目前我们正在使用 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;
    }
}

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

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

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

请注意,我已将 ClientSecretScopeSecret 设置为相同的值,因此我希望它能正常工作。

我是不是忘记做某事了?

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

为此,请将您的 ValidationMode 更改为 ValidationMode.ValidationEndpointValidationMode.Both

来自文档:

ValidationMode can be either set to Local (JWTs only), ValidationEndpoint (JWTs and reference tokens using the validation endpoint - and Both for JWTs locally and reference tokens using the validation endpoint (defaults to Both). - https://identityserver.github.io/Documentation/docsv2/consuming/options.html