zoukankan      html  css  js  c++  java
  • 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每次(可配置缓存)会去认证服务器获取信息。参考

     

  • 相关阅读:
    win10电脑只有自带浏览器能上网
    Android Studio环境安装
    小白回归
    软件工程个人总结
    学习进度第十六周
    学习进度第十五周
    第二阶段冲刺(第十天)
    《大道至简》阅读笔记03——语言只是种工具
    学习进度第十四周
    第二阶段冲刺(第九天)
  • 原文地址:https://www.cnblogs.com/ddrsql/p/7887083.html
Copyright © 2011-2022 走看看