C# IdentityServer最佳实践结合隐式和RessourceOwner工作流

C# IdentityServer最佳实践结合隐式和RessourceOwner工作流,c#,asp.net-web-api,oauth,openid,identityserver3,C#,Asp.net Web Api,Oauth,Openid,Identityserver3,给定: 支持隐式和资源所有者流的身份服务器。(见下文) 使用IdentityServerBearerTokenAuthentication的Api。因此,它基本上用一个密码交换一个用于身份验证的令牌 使用隐式工作流进行身份验证的UI 现在我可以从identity server获得一个承载令牌,通过它我可以访问受保护的api方法 作为一个用户,我也可以使用隐式流登录并查看受保护的视图 问题 当登录的WebFrontEndUser想要访问受保护的API时,就会出现问题 用户使用隐式流在ui中登录。经

给定: 支持隐式和资源所有者流的身份服务器。(见下文)

使用IdentityServerBearerTokenAuthentication的Api。因此,它基本上用一个密码交换一个用于身份验证的令牌

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

现在我可以从identity server获得一个承载令牌,通过它我可以访问受保护的api方法

作为一个用户,我也可以使用隐式流登录并查看受保护的视图

问题 当登录的WebFrontEndUser想要访问受保护的API时,就会出现问题

用户使用隐式流在ui中登录。经过身份验证后,他尝试访问受保护的api。 Api返回他未被授权的消息

如何配置环境,以便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
            });
app.UseIdentityServerBearerTokenAuthentication(new IdentityServer3.AccessTokenValidation.IdentityServerBearerTokenAuthenticationOptions()
        {
            Authority = identServer
        });
  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"
                    }
                }
WebApi配置

   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
            });
app.UseIdentityServerBearerTokenAuthentication(new IdentityServer3.AccessTokenValidation.IdentityServerBearerTokenAuthenticationOptions()
        {
            Authority = identServer
        });
  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"
                    }
                }
识别服务器客户端配置

   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
            });
app.UseIdentityServerBearerTokenAuthentication(new IdentityServer3.AccessTokenValidation.IdentityServerBearerTokenAuthenticationOptions()
        {
            Authority = identServer
        });
  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"
                    }
                }
新客户端
{
启用=真,
ClientId=“foo_implicit”,
ClientName=“foo站点”,
ClientSecrets=新列表
{
新秘密(“foo.Sha256())
},
流=流。隐式,
AllowedScopes=新列表
{
Constants.StandardScopes.OpenId,
常量.StandardScopes.Profile,
“读”
},
重定向URI=新列表()
{
"http://localhost/foo/"
}
},
新客户
{
启用=真,
ClientId=“foo”,
ClientName=“foo-api”,
ClientSecrets=新列表
{
新秘密(“foo.Sha256())
},
Flow=Flows.ResourceOwner,
AllowedScopes=新列表
{
Constants.StandardScopes.OpenId,
“读”
}
}

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

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

Notifications = new OpenIdConnectAuthenticationNotifications
{
    SecurityTokenValidated = x =>
    {
        x.AuthenticationTicket.Identity.AddClaim(new Claim("access_token", x.ProtocolMessage.AccessToken));
        return Task.FromResult(0);
    }
}
此外,您的
IdentityServerBealerTokenAuthenticationOptions
应说明令牌访问所需的一个或多个作用域。否则,来自该机构的任何访问令牌都可以访问您的API。有关此操作的更多详细信息,请参阅

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

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

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

Notifications = new OpenIdConnectAuthenticationNotifications
{
    SecurityTokenValidated = x =>
    {
        x.AuthenticationTicket.Identity.AddClaim(new Claim("access_token", x.ProtocolMessage.AccessToken));
        return Task.FromResult(0);
    }
}
此外,您的
IdentityServerBealerTokenAuthenticationOptions
应说明令牌访问所需的一个或多个作用域。否则,来自该机构的任何访问令牌都可以访问您的API。有关此操作的更多详细信息,请参阅

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