根据模板创建项目
https://identityserver4.readthedocs.io/en/latest/quickstarts/0_overview.html
使用终端输入dotnet new -i IdentityServer4.Templates
安装模板。
安装之后,有以下6个模板。
使用最后一个创建。
项目测试
修改Config
Config.cs中IdentityResources
代表身份资源,ApiScopes
主要用于为Client提供accesstoken中的scope声明的值。Client
客户端。
将Config.cs
中Clients
客户端只保留 GrantTypes.ClientCredentials
授权方式。
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
using IdentityServer4;
using IdentityServer4.Models;
using System.Collections.Generic;
namespace ids4
{
public static class Config
{
public static IEnumerable<IdentityResource> IdentityResources =>
new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
};
public static IEnumerable<ApiScope> ApiScopes =>
new ApiScope[]
{
new ApiScope("scope1","myApi"),
};
public static IEnumerable<Client> Clients =>
new Client[]
{
new Client
{
ClientId = "console client",
ClientName = "Client Credentials Client",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets = { new Secret("511536EF-F270-4058-80CA-1C89C192F69A".Sha256()) },
AllowedScopes =
{
"scope1",
IdentityServerConstants.StandardScopes.OpenId
}
}
};
}
}
新建项目ApiResourceWebApi项目
Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
namespace ApiResourceWebApi
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false
};
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints => endpoints.MapControllers());
}
}
}
新建Controllers
文件夹。
新建IdentityController
类。
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Linq;
namespace ApiResourceWebApi.Controllers
{
[Route("identity")]
[Authorize]
public class IdentityController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
}
}
}
注意该项目启动端口要和IDS项目启动端口不一样。
新建Console
客户端
安装IdentityModel Nuget包
using IdentityModel.Client;
using Newtonsoft.Json.Linq;
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace ConsoleClient
{
internal class Program
{
static async Task Main(string[] args)
{
// discovery
var client = new HttpClient();
var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000/");
if (disco.IsError)
{
Console.WriteLine(disco.Error);
return;
}
// request access token
var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest()
{
Address = disco.TokenEndpoint,
ClientId = "console client",
ClientSecret = "511536EF-F270-4058-80CA-1C89C192F69A",
// openid 是获取用户信息的,而ClientCredentials不代表任何用户,获取openid显然不合理的
Scope = "scope1"
});
if (tokenResponse.IsError)
{
Console.WriteLine(tokenResponse.Error);
return;
}
// call Identity Resource API
var apiClient = new HttpClient();
apiClient.SetBearerToken(tokenResponse.AccessToken);
var response = await apiClient.GetAsync("http://localhost:5002/identity");
if (!response.IsSuccessStatusCode)
{
Console.WriteLine(response.StatusCode);
}
else
{
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(JArray.Parse(content));
}
Console.ReadKey();
}
}
}
这样记录意义不大。需详细的过程化记录。