一、背景
IdentityServer4的介绍将不再叙述,百度下可以找到,且官网的快速入门例子也有翻译的版本。这里主要从Client应用场景方面介绍对IdentityServer4的应用。
首先简要介绍ID Token和Access Token:
Access Token是授权第三方客户端访问受保护资源的令牌。 ID Token是第三方客户端标识用户身份认证的问令牌,是JSON Web Token格式。
二、Client应用场景介绍
Client类是为OpenID Connect或OAuth 2.0 协议建模的。
我们先看官网快速入门中给的Client例子
里面主要介绍四种Client应用场景。
(1)客户端模式(AllowedGrantTypes = GrantTypes.ClientCredentials)
这是一种最简单的授权方式,应用于服务于服务之间的通信,token通常代表的是客户端的请求,而不是用户。
使用这种授权类型,会向token endpoint发送token请求,并获得代表客户机的access token。客户端通常必须使用token endpoint的Client ID和secret进行身份验证。
适用场景:用于和用户无关,服务与服务之间直接交互访问资源
(2)密码模式(ClientAllowedGrantTypes = GrantTypes.ResourceOwnerPassword)
该方式发送用户名和密码到token endpoint,向资源服务器请求令牌。这是一种“非交互式”授权方法。
官网上称,为了解决一些历史遗留的应用场景,所以保留了这种授权方式,但不建议使用。
适用场景:用于当前的APP是专门为服务端设计的情况。
(3)混合模式和客户端模式(ClientAllowedGrantTypes =GrantTypes.HybridAndClientCredentials)
ClientCredentials授权方式在第一种应用场景已经介绍了,这里主要介绍Hybrid授权方式。Hybrid是由Implicit和Authorization code结合起来的一种授权方式。其中Implicit用于身份认证,ID token被传输到浏览器并在浏览器进行验证;而Authorization code使用反向通道检索token和刷新token。
推荐适用Hybrid模式。
适用场景:用于MVC框架,服务器端 Web 应用程序和原生桌面/移动应用程序。
(4)简化模式(ClientAllowedGrantTypes =GrantTypes.Implicit)
Implicit要么仅用于服务端和JavaScript应用程序端进行身份认证,要么用于身份身份验证和access token的传输。
在Implicit中,所有token都通过浏览器传输的。
适用场景:JavaScript应用程序。
三、Server端搭建
为了介绍IdentityServer4的Client应用场景,我们需要先搭建IdentityServer服务端。
这里搭建的是使用EF Core来做数据操作,保存到SQL Server中。
(1)新建API项目
(2)安装IdentityServer4.EntityFramework包
(3)安装IdentityServer4包
(4)右键项目的属性,编辑项目的.csproj文件
添加如下元素
<ItemGroup><DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" /></ItemGroup>
如图:
(5)cmd管理员身份进入项目目录路径(D:\IdentityServer4\Server),运行:dotnet ef
(6)项目内添加Config.cs类,代码如下
public class Config
{
public static List<TestUser> GetUsers()
{
return new List<TestUser>
{
new TestUser
{
SubjectId = "1",
Username = "alice",
Password = "password",
Claims = new List<Claim>(){new Claim(JwtClaimTypes.Role,"superadmin") }
},
new TestUser
{
SubjectId = "2",
Username = "bob",
Password = "password",
Claims = new List<Claim>
{
new Claim("name", "Bob"),
new Claim("website", "https://bob.com")
},
}
};
}
public static IEnumerable<Client> GetClients()
{
// client credentials client
return new List<Client>
{
new Client
{
ClientId = "Client",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowedScopes = { "api1" }
},
// resource owner password grant client
new Client
{
ClientId = "ro.client",
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowedScopes = { "api1" }
},
// OpenID Connect hybrid flow and client credentials client (MVC)
new Client
{
ClientId = "mvc",
ClientName = "MVC Client",
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
ClientSecrets =
{
new Secret("secret".Sha256())
},
RedirectUris = { "http://localhost:5002/signin-oidc" },
PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api1"
},
AllowOfflineAccess = true
},
// JavaScript Client
new Client
{
ClientId = "js",
ClientName = "JavaScript Client",
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
RedirectUris = { "http://localhost:5003/callback.html" },
PostLogoutRedirectUris = { "http://localhost:5003/index.html" },
AllowedCorsOrigins = { "http://localhost:5003" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api1"
},
}
};
}
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
};
}
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource("api1", "My API")
};
}
添加引用:
using IdentityModel;
using IdentityServer4;
using IdentityServer4.Models;
using IdentityServer4.Test;
using System.Collections.Generic;
using System.Security.Claims;
(7)编辑Startup.cs文件的ConfigureServices方法,改成如下代码。
添加引用:
using Microsoft.EntityFrameworkCore;
using System.Reflection;
(8)cmd管理员身份进入到项目目录路径(D:\IdentityServer4\Server\Server),注意,多了一层目录,分别运行以下两条指令:
运行完后,项目中会多了一个Data文件夹
(9)在Startup.cs中添加初始化数据库方法。
添加引用:
using IdentityServer4.EntityFramework.DbContexts;
using IdentityServer4.EntityFramework.Mappers;
(10)在Startup.cs中的Configure方法修改成以下代码。
到这里,把项目以控制台形式运行
点击运行,可以跑起来,且生成数据库IdentityServer4DB。
关于Client的说明可以查阅官网资料:https://identityserver4.readthedocs.io/en/release/reference/client.html
源码地址:https://github.com/Bingjian-Zhu/Server.git
服务端准备好之后,下篇文章开始介绍Client客户端的应用。