IdentityServer BestPractive 结合隐式和 RessourceOwner 工作流

IdentityServer BestPractive Combine Implicit and RessourceOwner Workflow

给定: 支持隐式和资源所有者流的 Identity Server。 (配置见下)

使用 IdentityServerBearerTokenAuthentication 的 Api。所以它基本上用密码交换用于 auth

的令牌

A UI 使用隐式工作流进行身份验证。

现在我可以从身份服务器获取不记名令牌,通过它我可以访问受保护的 api 方法。

作为用户,我还可以使用隐式流程登录并查看受保护的视图。

问题 当登录的 WebFrontEndUser 想要访问受保护的 API.

时,问题就来了

用户使用隐式流程在 ui 中登录。在他通过身份验证后,他尝试访问受保护的 api。 Apireturns表示他没有授权。

如何配置环境以便 api 使用来自用户 cookie 的 openid 信息?

网站配置

   app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            });

            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                ClientId = "foo_implicit",
                Authority = identServer,
                RedirectUri = "http://localhost/foo/",
                ResponseType = "token id_token",
                Scope = "openid profile",
                SignInAsAuthenticationType = DefaultAuthenticationTypes.ApplicationCookie
            });

WebApi 配置

app.UseIdentityServerBearerTokenAuthentication(new IdentityServer3.AccessTokenValidation.IdentityServerBearerTokenAuthenticationOptions()
        {
            Authority = identServer
        });

IdentityServer 客户端配置

  new Client
                {
                    Enabled = true,
                    ClientId = "foo_implicit",
                    ClientName = "foo Site",
                    ClientSecrets = new List<Secret>
                    {
                        new Secret("foo".Sha256())
                    },
                    Flow = Flows.Implicit,
                    AllowedScopes = new List<string>
                    {
                        Constants.StandardScopes.OpenId,
                        Constants.StandardScopes.Profile,
                        "read"
                    },
                    RedirectUris = new List<string>()
                    {
                        "http://localhost/foo/"
                    }
                },
                new Client
                {
                    Enabled = true,
                    ClientId = "foo",
                    ClientName = "foo api",
                    ClientSecrets = new List<Secret>
                    {
                        new Secret("foo".Sha256())
                    },
                    Flow = Flows.ResourceOwner,
                    AllowedScopes = new List<string>
                    {
                        Constants.StandardScopes.OpenId,
                        "read"
                    }
                }

使用 OpenID Connect,您可以在身份验证期间请求身份和访问令牌。您已经在身份验证期间获得了访问令牌(响应类型 token),因此我会抓住它并使用它来访问 API。这将避免需要单独的资源所有者客户端。

您可以使用 OpenIdConnectAuthenticationOptionsOpenIdConnectAuthenticationNotifications 属性 获取此访问令牌,例如:

Notifications = new OpenIdConnectAuthenticationNotifications
{
    SecurityTokenValidated = x =>
    {
        x.AuthenticationTicket.Identity.AddClaim(new Claim("access_token", x.ProtocolMessage.AccessToken));
        return Task.FromResult(0);
    }
}

此外,您的 IdentityServerBearerTokenAuthenticationOptions 应说明令牌访问所需的一个或多个范围。否则,来自该机构的任何访问令牌都可以访问您的 API。有关详细信息,请参阅 documentation

app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
    Authority = identServer,
    RequiredScopes = new[] { "api1" }
});