Skip to content
On this page

Hybrid

HybridOpenID Connect协议中定义授权方式,它结合了Authorization codeimplicit两种授权方式。Hybrid授权方式可以通过客户端配置ResponseType属性来选择Code/Id Token, Code/TokenCode/Id Token/Token令牌组合方式,用户在Identity Server认证通过后会返回Authorization code给客户端浏览器,接下来根据客户端配置的ResponseType不同,授权过程也略有区别。Hybrid flow的三种令牌组合都需要Authorization code,因此常用于保护机密客户端。oidc-client不支持Hybrid flow

1. Identity Server

本节我们继续使用Authorization Code章节中的IdentityServer服务。下面我们简单来演示如何进行客户端注册。本节代码已分享到Github

csharp
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

csharp
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 dataAPI资源,刷新令牌,注销登录等行为方式也与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

Released under the MIT License.