IdentityServer4在.Net Core 3.1中应用(密码授权模式)
前言
密码授权模式是在客户端授权模式的基础代码上修改的,没有代码的可以查看我之前的那片文章。客户端验证模式
一、修改IdentityServer认证服务器?
1.1 修改Config文件
修改IdentityServer认证服务器项目中Config.cs类文件,添加密码模式的客户端。并配置基于内存的用户和密码。
using IdentityServer4.Models;
using IdentityServer4.Test;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Sample.IdentityServer
{
public class Config
{
/// <summary>
/// 配置ApiResource
/// </summary>
/// <returns></returns>
public static IEnumerable<ApiResource> ApiResources()
{
return new List<ApiResource>() {
//将多个具体的ApiScope归为一个ApiResource。可将多个Api范围进行分组,
//这样分的好处是对Api资源分的更细,在授权时,可更精细的控制。
new ApiResource("Sample","IdentityServer4学习用例"){
Scopes={ "sample_api","demo_api" }
}
};
}
/// <summary>
/// 设置具体的Api的范围
/// </summary>
public static IEnumerable<ApiScope> ApiScopes()
{
return new List<ApiScope>(){
new ApiScope("sample_api","Sample Api"),
new ApiScope("demo_api","Demo Api")
};
}
/// <summary>
/// 配置客户端应用
/// </summary>
public static IEnumerable<Client> Clients()
{
return new List<Client> {
//客户端模式
new Client{
//客户端ID
ClientId = "sample_api",
//认证秘钥
ClientSecrets = { new Secret("sample_client_secret".Sha256()) },
//认证模式:设置为客户端模式
AllowedGrantTypes = GrantTypes.ClientCredentials,
//设置客户端有权访问的范围
AllowedScopes = { "sample_api" }
},
//密码模式
new Client{
//客户端ID
ClientId="sample_api_password",
//认证秘钥
ClientSecrets = { new Secret("sample_client_secret".Sha256()) },
//认证模式:设置为客户端模式
AllowedGrantTypes=GrantTypes.ResourceOwnerPassword,
//设置客户端有权访问的范围
AllowedScopes={"sample_api" }
},
};
}
/// <summary>
/// 配置可以被认证和授权的用户信息,存在于内存上。
/// </summary>
/// <returns></returns>
public static List<TestUser> GetTestUsers()
{
return new List<TestUser>()
{
new TestUser{
SubjectId="1",
Username="demo",
Password="456"
},
new TestUser{
SubjectId="2",
Username="test",
Password="456"
}
};
}
}
}
1.2 修改DI容器
在Startup.ConfigureServices()方法中向DI容器添加关于加载用户信息的方法。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
//将IdentityServer注册到DI容器当中
services.AddIdentityServer()
.AddDeveloperSigningCredential() //在开发模式下自动生成JWT的秘钥,实际运行过程中需要自己生成秘钥。
//.AddSigningCredential()运用自己生成的秘钥。
.AddInMemoryApiResources(Config.ApiResources())//注册ApiResource
.AddInMemoryApiScopes(Config.ApiScopes())// 注册API的范围
.AddInMemoryClients(Config.Clients())//注册Api的客户端
.AddTestUsers(Config.GetTestUsers());//加载用户信息 (如果是客户端模式,可以不用写此方法)
}
至此,IdentityServer认证服务器就修改完成了。
二、修改客户端
在客户端项目中修改关于密码方式的访问请求。
using System;
using System.Net.Http;
using System.Threading.Tasks;
using IdentityModel.Client;
using Newtonsoft.Json.Linq;
namespace Sample.Client
{
class Program
{
static async Task Main(string[] args)
{
var client = new HttpClient();
var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");
if (disco.IsError)
{
Console.WriteLine(disco.Error);
return;
}
//客户端模式
//var tokenRequest = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
//{
// Address = disco.TokenEndpoint,
// ClientId = "sample_api",
// ClientSecret = "sample_client_secret"
//});
//密码模式
var tokenRequest = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = "sample_api_password",
ClientSecret = "sample_client_secret",
UserName = "demo",
Password = "456"
});
Console.WriteLine("IdentityServer4服务器返回的结果 : {0}", tokenRequest.Json);
var apiClient = new HttpClient();
apiClient.SetBearerToken(tokenRequest.AccessToken);
var response = await apiClient.GetAsync("http://localhost:6000/WeatherForecast");
if (!response.IsSuccessStatusCode)
{
Console.WriteLine(response.StatusCode);
return;
}
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(JArray.Parse(content));
Console.ReadKey();
}
}
}
三、验证
3.1 启动项目
启动IdentityServer认证服务器和API资源服务器项目。
3.2 获取Access_Token(Postman)
与请求客户端模式不同,这里需要修改参数。
将client_id的参数修改为 sample_api_password
将grant_type的参数改为 password
添加username,参数为 demo
添加password,参数为 456
如上图所示,已经正确的拿到了Access_Token。
3.3 携带Access_Token请求API(Postman)
和客户端模式一样,将获取到的Access_Token填写到参数框中。发送请求。
如图所示,我们已经拿到了API资源服务器所返回的参数。
3.4 客户端验证
下面,我们运行客户端程序,查看返回结果。
客户端同样拿到了相同的数据,至此,密码授权模式完成。
如需要源码,请在Gitee上下载:IdentityServer4Demo