IdentityServer4 学习笔记-定义客户端登录

393 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情

1.定义到服务器通信的客户端

在这种情况下,没有交互式用户 - 服务(aka client)想要与API(aka scope)进行通信:

客户端表示可以从身份服务器请求令牌的应用程序,详细信息各不相同,但通常会为客户端定义以下常用设置:

  • 唯一的客户ID
  • 如果需要的秘密
  • 允许与令牌服务的交互(称为授权类型)
  • 身份和/或访问令牌发送到的网络位置(称为重定向URI)
  • 允许客户端访问的范围列表(也称为资源)
public class Clients
{
    public static IEnumerable<Client> Get()
    {
        return new List<Client>
        {
            new Client
            {
                ClientId = "service.client",
                ClientSecrets = { new Secret("secret".Sha256()) },

                AllowedGrantTypes = GrantTypes.ClientCredentials,
                AllowedScopes = { "api1", "api2.read_only" }
            }
        };
    }
}
2. 定义基于浏览器的客户端

客户端使用所谓的隐式流来从JavaScript请求身份和访问令牌:

var jsClient = new Client
{
    ClientId = "js",
    ClientName = "JavaScript Client",
    ClientUri = "http://identityserver.io",

    AllowedGrantTypes = GrantTypes.Implicit,
    AllowAccessTokensViaBrowser = true,

    RedirectUris =           { "http://localhost:7017/index.html" },
    PostLogoutRedirectUris = { "http://localhost:7017/index.html" },
    AllowedCorsOrigins =     { "http://localhost:7017" },

    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        IdentityServerConstants.StandardScopes.Email,

        "api1", "api2.read_only"
    }
};
3. 定义服务器端Web应用程序

交互式服务器端(或本地桌面/移动)应用程序使用混合流。此流程为您提供最佳安全性,因为访问令牌仅通过反向通道调用传输(并允许您访问刷新令牌):

var mvcClient = new Client
{
    ClientId = "mvc",
    ClientName = "MVC Client",
    ClientUri = "http://identityserver.io",

    AllowedGrantTypes = GrantTypes.Hybrid,
    AllowOfflineAccess = true,
    ClientSecrets = { new Secret("secret".Sha256()) },

    RedirectUris =           { "http://localhost:21402/signin-oidc" },
    PostLogoutRedirectUris = { "http://localhost:21402/" },
    FrontChannelLogoutUri =  "http://localhost:21402/signout-oidc",

    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        IdentityServerConstants.StandardScopes.Email,

        "api1", "api2.read_only"
    },
};
4.在appsettings.json中定义客户端

AddInMemoryClients扩展方法也支持从ASP.NET Core配置文件中添加客户端。这允许直接从appsettings.json文件定义静态客户端:

"IdentityServer": {
  "IssuerUri": "urn:sso.company.com",
  "Clients": [
    {
      "Enabled": true,
      "ClientId": "local-dev",
      "ClientName": "Local Development",
      "ClientSecrets": [ { "Value": "<Insert Sha256 hash of the secret encoded as Base64 string>" } ],
      "AllowedGrantTypes": [ "implicit" ],
      "AllowedScopes": [ "openid", "profile" ],
      "RedirectUris": [ "https://localhost:5001/signin-oidc" ],
      "RequireConsent": false
    }
  ]
}

然后将配置部分传递给AddInMemoryClients方法:

AddInMemoryClients(configuration.GetSection("IdentityServer:Clients"))
5. Cookie身份验证

使用由ASP.NET Core中的cookie身份验证处理程序管理的cookie来跟踪身份验证。

IdentityServer注册了两个cookie处理程序(一个用于身份验证会话,另一个用于临时外部cookie)。默认情况下使用,如果要手动引用,可以从IdentityServerConstants类(DefaultCookieAuthenticationSchemeExternalCookieAuthenticationScheme)中获取它们的名称。

只公开这些cookie的基本设置(到期和滑动),如果需要更多控制,可以注册自己的cookie处理程序。当使用ASP.NET Core中的AddAuthentication时,IdentityServer使用与AuthenticationOptions上配置的DefaultAuthenticateScheme匹配的cookie处理程序。

如果希望使用自己的cookie身份验证处理程序,则必须自己配置它。这必须在ConfigureServices DI(AddIdentityServer)中注册IdentityServer之后完成。例如:

services.AddIdentityServer()
    .AddInMemoryClients(Clients.Get())
    .AddInMemoryIdentityResources(Resources.GetIdentityResources())
    .AddInMemoryApiResources(Resources.GetApiResources())
    .AddDeveloperSigningCredential()
    .AddTestUsers(TestUsers.Users);

services.AddAuthentication("MyCookie")
    .AddCookie("MyCookie", options =>
    {
        options.ExpireTimeSpan = ...;
    });
6. 登录用户界面和身份管理系统

IdentityServer不为用户身份验证提供任何用户界面或用户数据库。 这些是希望自己提供或开发的东西。
如果需要基本UI的起点(登录,注销,同意和管理授权针对内存数据库对用户进行身份验证。 您可以通过访问真实用户存储来替换这些位。

当IdentityServer在授权端点收到请求且未对用户进行身份验证时,将用户重定向到已配置的登录页面。 必须通过选项上的UserInteraction设置(默认/account/login)通知IdentityServer登录页面的路径,将传递returnUrl参数,通知登录页面,一旦登录完成,应该重定向用户。

7. Windows身份验证

在支持的平台上,可以使用IdentityServer使用Windows身份验证对用户进行身份验证(例如,针对Active Directory),当前使用以下命令托管IdentityServer时,Windows身份验证可用:

  • Kestrel在Windows上使用IIS和IIS集成包
  • Windows上的HTTP.sys服务器

在这两种情况下,使用方案“Windows”HttpContext上使用ChallengeAsync API来触发Windows身份验证帐户控制器实现了必要的逻辑。

使用Kestrel时,必须运行“behind”IIS并使用IIS集成:

var host = new WebHostBuilder()
    .UseKestrel()
    .UseUrls("http://localhost:5000")
    .UseContentRoot(Directory.GetCurrentDirectory())
    .UseIISIntegration()
    .UseStartup<Startup>()
    .Build();

使用该WebHost.CreateDefaultBuilder方法设置时,会自动配置WebHostBuilder
IIS(或IIS Express)中的虚拟目录也必须启用Windows并启用匿名身份验证。
IIS集成层将Windows身份验证处理程序配置为DI,可以通过身份验证服务调用。通常在IdentityServer中,建议禁用此自动行为。这是在ConfigureServices

services.Configure<IISOptions>(iis =>
{
    iis.AuthenticationDisplayName = "Windows";
    iis.AutomaticAuthentication = false;
});