Hybrid
Hybrid是OpenID Connect协议中定义授权方式,它结合了Authorization code和implicit两种授权方式。Hybrid授权方式可以通过客户端配置ResponseType属性来选择Code/Id Token, Code/Token或Code/Id Token/Token令牌组合方式,用户在Identity Server认证通过后会返回Authorization code给客户端浏览器,接下来根据客户端配置的ResponseType不同,授权过程也略有区别。Hybrid flow的三种令牌组合都需要Authorization code,因此常用于保护机密客户端。oidc-client不支持Hybrid flow。
1. Identity Server
本节我们继续使用Authorization Code章节中的IdentityServer服务。下面我们简单来演示如何进行客户端注册。本节代码已分享到Github。
public static IEnumerable<Client> Clients =>
new[]
{
new Client
{
ClientId = "HybridMvcClient",
ClientSecrets = {new Secret("HybridMvcClient".Sha256())},
AllowedGrantTypes = GrantTypes.Hybrid,
AllowedScopes =
{
"WeatherApi",
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile
},
RedirectUris = {"https://localhost:9000/signin-oidc"},
FrontChannelLogoutUri = "https://localhost:9000/signout-oidc",
PostLogoutRedirectUris = {"https://localhost:9000/signout-callback-oidc"},
AllowOfflineAccess = true,
RequirePkce = false, // 关闭 authorization code请求过程验证proof key
AlwaysIncludeUserClaimsInIdToken = true // 在IdToken中包含所有用户身份声明
}
};2. Client
这里API项目依然使用Client Credentials中的代码,不再赘述。
这里我们建立一个Asp.Net MVC程序作为客户端,客户端代码已共享至Github。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
var is4Configuration = Configuration.GetSection(nameof(IdentityServerOptions));
services.Configure<IdentityServerOptions>(is4Configuration);
var is4Options = is4Configuration.Get<IdentityServerOptions>();
services
.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.Authority = is4Options.Address;
options.ClientId = is4Options.ClientId;
options.ClientSecret = is4Options.ClientSecret;
options.ResponseType = OidcConstants.ResponseTypes.CodeIdToken;
options.SaveTokens = true;
options.RequireHttpsMetadata = false;
options.Scope.Clear();
foreach (var scope in is4Options.Scopes)
options.Scope.Add(scope.Name);
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
// 添加 claims 从忽略列表中移除等同于添加
options.ClaimActions.Remove("nbf");
options.ClaimActions.Remove("exp");
// 移除 claims
options.ClaimActions.DeleteClaim("sid");
options.ClaimActions.DeleteClaim("sub");
});
}Hybrid客户端配置除了ResponseType属性其它配置与Authorization code完全一致,不再赘述。
Hybrid访问Identity data和API资源,刷新令牌,注销登录等行为方式也与Authorization code完全一致,亦不再赘述。
3. Claims
Identity Server在用户认证后返回的Token/Id Token中包含的了认证的Claims。默认情况直接访问User.Claims只能拿到部分Claims,那是因为框架默认选择了部分Claims映射到User.Claims对象。
如有需要,开发者也可以手动添加或移除特定Claims,具体参见客户端33-38行代码。
如果要将用户Claims包含在Id Token中返回,可以在Identity Server注册客户端时设置 AlwaysIncludeUserClaimsInIdToken = true。