IdentityServer4之Client Credentials(客户端凭据许可)

IdentityServer4之Client Credentials(客户端凭据许可

参考

项目创建:0_overview1_client_credentials

概念:客户端凭据许可

 

认证服务端配置

认证服务ApiResource配置

new ApiResource("api1", "api项目 一")
{
    ApiSecrets = { new Secret("api1pwd".Sha256()) }
},

认证服务Client配置

//client credentials client
new Client
{
    ClientId = "client",
    // no interactive user, use the clientid/secret for authentication
    AllowedGrantTypes = GrantTypes.ClientCredentials,
//Jwt = 0;Reference = 1支持撤销; AccessTokenType
= AccessTokenType.Reference, // secret for authentication ClientSecrets = { new Secret("secret".Sha256()), new Secret("abc".Sha256()) }, // scopes that client has access to AllowedScopes = { "api1" } },

认证服务Startup配置

// configure identity server with in-memory stores, keys, clients and scopes
services.AddIdentityServer()
    .AddDeveloperSigningCredential()
    .AddInMemoryApiResources(Config.GetApiResources())
    .AddInMemoryClients(Config.GetClients());

配置完成启动访问http://localhost:5000/.well-known/openid-configuration

 

资源服务Api配置

资源服务器Startup配置

services.AddMvcCore()
    .AddAuthorization()
    .AddJsonFormatters();

services.AddAuthentication("Bearer")
    .AddIdentityServerAuthentication(options =>
    {
        options.Authority = "http://localhost:5000";
        options.RequireHttpsMetadata = false;

        options.ApiName = "api1";  
        options.ApiSecret = "api1pwd";  //对应ApiResources中的密钥
    });

添加接口

[Route("[controller]")]
[Authorize]
public class IdentityController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        var info = from c in User.Claims select new { c.Type, c.Value };
        var list = info.ToList();
        list.Add(new { Type = "api1返回", Value = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") });
        return new JsonResult(list);
    }
}

Client客户端

客户端与授权服务器进行身份验证并向令牌端点请求访问令牌。

授权服务器对客户端进行身份验证,如果有效,颁发访问令牌。

//credentials client
private void btnAuth_Click(object sender, EventArgs e)
{
    // discover endpoints from metadata
    Task<DiscoveryResponse> discoTask = DiscoveryClient.GetAsync(txtCCAuthSer.Text);
    discoTask.Wait();
    var disco = discoTask.Result;
    if (disco.IsError)
    {
        MessageBox.Show(disco.Error, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
        txtCCResult.Text = string.Empty;
        txtAccessToken.Text = string.Empty;
        return;
    }

    // request token
    var tokenClient = new TokenClient(disco.TokenEndpoint, txtCCClient.Text, txtCCSecret.Text);
    Task<TokenResponse> tokenTask = tokenClient.RequestClientCredentialsAsync(txtCCScopes.Text);
    tokenTask.Wait();
    var tokenResponse = tokenTask.Result;

    if (tokenResponse.IsError)
    {
        MessageBox.Show(tokenResponse.Error, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
        txtCCResult.Text = string.Empty;
        txtAccessToken.Text = string.Empty;
        return;
    }
    
    txtCCResult.Text = tokenResponse.Json.ToString();
    txtAccessToken.Text = tokenResponse.AccessToken;
}

调用Api

private void btnCallApi_Click(object sender, EventArgs e)
{
    // call api
    var client = new HttpClient();
    client.SetBearerToken(txtAccessToken.Text);

    var responseTask = client.GetAsync(txtCCApiUrl.Text);
    responseTask.Wait();
    var response = responseTask.Result;
    if (!response.IsSuccessStatusCode)
    {
        MessageBox.Show(response.StatusCode.ToString(), "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
        txtApiResult.Text = string.Empty;
    }
    else
    {
        var contentTask = response.Content.ReadAsStringAsync();
        contentTask.Wait();
        var content = contentTask.Result;
        txtApiResult.Text = JArray.Parse(content).ToString();
    }
}

 

获取token过程解析

Jwt形式获取access_token

通过IdentityModel发送请求

监听请求数据

客户端身份验证两种方式
1、Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3。

POST /connect/token HTTP/1.1
Connection: Keep-Alive
Content-Type: application/x-www-form-urlencoded
Accept: application/json
Authorization: Basic Y2xpZW50OnNlY3JldA==
Expect: 100-continue
Host: localhost:5000
MS-ASPNETCORE-TOKEN: 08de58f6-58ee-4f05-8d95-3829dde6ae09
X-Forwarded-For: [::1]:12112
X-Forwarded-Proto: http
Content-Length: 40
grant_type=client_credentials&scope=api1

2、client_id(客户端标识),client_secret(客户端秘钥)。

 

 

Reference形式获取access_token

将client的AccessTokenType设置为1

再次获取的access_token不包含Claim信息。

此时获取的access_token(加密后)对应PersistedGrants表中的key

 

调用Api资源服务过程解析

Jwt形式获取access_token调用Api

监听请求数据

api资源服务验证Jwt形式token会去认证服务器获取一次配置信息。

 

 

Reference形式获取access_token调用Api

 监听请求数据

 

api资源服务验证Reference形式token每次(可配置缓存)会去认证服务器获取信息。参考

 

 

posted @ 2017-11-23 23:42  ddrsql  阅读(6625)  评论(4编辑  收藏  举报