IdentityServer4[4]使用密码保护API资源

使用密码保护API资源(资源所有者密码授权模式)

资源所有者(Resource Owner)就是指的User,也就是用户。所以也称为用户名密码模式。相对于客户端凭证模式,增加了一个参与者User。通过User的用户名和密码向IdentityServer申请Access Token。这种模式下要求客户端不能存储密码,否则就存在密码泄露的风险,但是又不能确保第三方Client不存储密码。所以这种模式仅适用于受信任的客户端。

创建项目
  • IdentityServer的ASP.NET Core Web空项目,端口5000

  • Api的ASP.NET Core Web API项目,端口5001

  • Client的控制台项目

IdentityServer准备工作

定义API资源

public static IEnumerable<ApiResource> GetResources()
{
	return new List<ApiResource>()
	{
		new ApiResource("api","My Api")
	};
}

定义客户端

        public static IEnumerable<Client> GetClients()
        {
            return new List<Client>()
            {
                new Client()
                {
                    ClientId="pwdclient",
                    AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
                    ClientSecrets =
                    {
                        new Secret("secret".Sha256())
                    },
                    AllowedScopes = {"api"}
                }
            };
        }

配置IdentityServer

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddIdentityServer()
                .AddDeveloperSigningCredential()
                .AddInMemoryApiResources(Config.GetResources())
                .AddInMemoryClients(Config.GetClients())
                .AddTestUsers(Config.GetUsers());
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseIdentityServer();
            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        }
    }
API准备

在API控制器上,增加[Authorize]特性(授权)

	[Route("api/[controller]")]
    [ApiController]
    [Authorize]
    public class ValuesController : ControllerBase

Startup增加如下代码:

    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthentication("Bearer")
                .AddIdentityServerAuthentication(options =>
                {
                    options.Authority = "http://localhost:5000";
                    options.RequireHttpsMetadata = false;
                    //options.ApiName = "Home";//不设置此参数,代表所有接口全部使用权限
                });
          				services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseAuthentication();
            app.UseMvc();
        }
    }

使用postman调用

创建客户端

IdentityModel 包括用于发现 IdentityServer 各个终结点(EndPoint)的客户端库。这样只需要知道 IdentityServer 的地址 - 可以从元数据中读取实际的各个终结点地址:

var client = new HttpClient();
var disdoc = client.GetDiscoveryDocumentAsync("http://localhost:5000").Result;
if (disdoc.IsError)
{
	Console.WriteLine(disdoc.Error);
}

获取token

var tokenResponse = client.RequestPasswordTokenAsync(new PasswordTokenRequest()
{
    Address = disdoc.TokenEndpoint,
    ClientId = "pwdclient",
    ClientSecret = "secret",
    Scope = "api",

    UserName = "Test1",
    Password = "123456"

}).Result;

if (tokenResponse.IsError)
{
    Console.WriteLine(tokenResponse.Error);
}
else
{
    Console.WriteLine(tokenResponse.Json);
}

调用API

HttpClient httpClient = new HttpClient();
httpClient.SetBearerToken(tokenResponse.AccessToken);
var response = httpClient.GetAsync("http://localhost:5001/api/values").Result;
if (response.IsSuccessStatusCode)
{
    Console.WriteLine(response.Content.ReadAsStringAsync().Result);
}

Console.ReadLine();

IdentityServer4 中文文档与实战

IdentityServer4 知多少

jessetalk视频教程

posted @ 2020-07-31 08:58  蜗牛的希望  阅读(425)  评论(0编辑  收藏  举报