C# IdentityServer最佳实践结合隐式和RessourceOwner工作流
给定: 支持隐式和资源所有者流的身份服务器。(见下文) 使用IdentityServerBearerTokenAuthentication的Api。因此,它基本上用一个密码交换一个用于身份验证的令牌 使用隐式工作流进行身份验证的UI 现在我可以从identity server获得一个承载令牌,通过它我可以访问受保护的api方法 作为一个用户,我也可以使用隐式流登录并查看受保护的视图 问题 当登录的WebFrontEndUser想要访问受保护的API时,就会出现问题 用户使用隐式流在ui中登录。经过身份验证后,他尝试访问受保护的api。 Api返回他未被授权的消息 如何配置环境,以便api使用来自用户cookie的openid信息 网站确认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中登录。经
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" }
});