Identity Server 4

时间:2017-09-07 03:09:50

标签: asp.net-core oauth-2.0 identityserver4

初级水平查询提醒。 IdentityServer4 Tutorial在完成教程后,我推断的是 -

  1. 我创建了一个授权服务器,其作用是通过适当的身份验证为客户端发出令牌。
  2. 我的授权服务器首先运行,包括API和客户端的信息和定义。
  3. API具有一个身份验证中间件,可以验证传入令牌,以确保它来自受信任的来源及其范围。
  4. 客户端从授权服务器请求令牌,然后使用收到的令牌向API发送请求。
  5. 对于所有这些,我必须首先运行授权服务器,然后运行API,然后运行客户端。我的要求是我不需要一个单独运行的启动和停止服务器来处理身份验证。我有一个API,我需要它作为授权服务器加倍。这可能吗?是否有可能API使用IdentityServer4生成令牌,验证它们然后倾向于请求。

1 个答案:

答案 0 :(得分:6)

虽然通常Auth服务器将与资源服务器分开,但并非如此。您可以将所有内容添加到一个应用程序中。这是一个例子。

  1. 创建一个新的ASP.NET Core(我使用2.0)Web API应用程序。
  2. Install-Package IdentityServer4 -Version 2.0.0-rc1(在撰写本文时,rc1是支持.NET Core 2.x的版本)
  3. Install-Package Microsoft.AspNetCore.Authentication.JwtBearer
  4. [Authorize]上从模板
  5. 设置ValuesController
  6. 将此代码添加到Configure(...) class Startup以上的app.UseMvc()中的// calls app.UseAuthentication() for us // See: http://docs.identityserver.io/en/release/quickstarts/6_aspnet_identity.html app.UseIdentityServer();

    ConfigureServices(...)
  7. 将此代码添加到class Startup中的services.AddIdentityServer() .AddDeveloperSigningCredential() .AddInMemoryApiResources(new[] { new ApiResource { Name = "MyApi", ApiSecrets = { new Secret("supersecret".Sha256()) }, Scopes = { new Scope("myapi") }, } }) .AddInMemoryClients(new[] { new Client { ClientId = "api", ClientSecrets = { new Secret("supersecret".Sha256()) }, AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, AllowedScopes = { "myapi" }, } }) .AddTestUsers(new List<TestUser> { new TestUser { SubjectId = "some-unique-id-12345678980", Username = "john", Password = "123456" } }); services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(opts => { opts.Authority = "http://localhost:51689"; opts.Audience = "MyApi"; opts.RequireHttpsMetadata = !env.IsDevelopment(); });

    http://localhost:51689/.well-known/openid-configuration
  8. 如果您现在 F5 该应用程序将显示一个空页面,因为&#34; 401 Unauthorized&#34;响应。您现在也可以检查此端点:curl -X POST \ http://localhost:51689/connect/token \ -H 'authorization: Basic YXBpY2xpZW50aWQ6c3VwZXJzZWNyZXQ=' \ -H 'cache-control: no-cache' \ -H 'content-type: application/x-www-form-urlencoded' \ -d 'username=john&password=123456&grant_type=password' (当然还有您的开发端口)。

    您现在也可以这样做:

    authorization

    请注意,"apiclientid:supersecret"标头包含表示字符串{ "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjczODhkMjY0MDg4Y2NjOGRiZTcwODIzZGIxYzY3ZWNkIiwidHlwIjoiSldUIn0.eyJuYmYiOjE1MDUwODE3OTAsImV4cCI6MTUwNTA4NTM5MCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MTY4OSIsImF1ZCI6WyJodHRwOi8vbG9jYWxob3N0OjUxNjg5L3Jlc291cmNlcyIsIk15QXBpIl0sImNsaWVudF9pZCI6ImFwaWNsaWVudGlkIiwic3ViIjoic29tZS11bmlxdWUtaWQtMTIzNDU2Nzg5ODAiLCJhdXRoX3RpbWUiOjE1MDUwODE3OTAsImlkcCI6ImxvY2FsIiwic2NvcGUiOlsibXlhcGkiXSwiYW1yIjpbInB3ZCJdfQ.sxWodlJKDJgjoOj-8njZ8kONOqiKgj3E5YlKXGX5cz-WqUK7RHKJacNX09D00Y8YtmZpkc5OrY0xzOx7UuSAtDku4oOX_1o38XEGJPBSJHdjqgVGSOU-hwDkzin8HSRJ0Kna1vM3ZzTh80cFTVhP8h903GAPRrAyV8PtRXnwV0CPel8NdvML6dV-mfDpGi0l7crp-TPnH4nIG0olpRYUPV5EsgCVMG9vswnOnKz3RPOGaU8yJy7_9mbQW5GHKfN0J6swiSt5rY3NKs_t1P9-tnCDKBOAafaXjLEO3Kx4fP4xTgwK92uKcEDDnRZo_-T0CkBxnSQm0oz1sUyrW8_3Pg", "expires_in": 3600, "token_type": "Bearer" } 的base64编码字符串。这应该给你一个这样的结果:

    [Route("api/token")]
    public class TokenController
    {
        [HttpPost("request")]
        public async Task<JObject> Request(string username, string password)
        {
            var tokenClient = new TokenClient("http://localhost:51689/connect/token", "apiclientid", "supersecret");
            var tokenResponse = await tokenClient.RequestResourceOwnerPasswordAsync(username, password);
    
            if (tokenResponse.IsError) { /* Log failed login attempt! */ } 
    
            return tokenResponse.Json;
        }
    }
    

    除了切换到其他身份验证流程的选项之外,您还可以添加如下控制器方法:

    curl -X POST \
      http://localhost:51689/api/token/request \
      -H 'cache-control: no-cache' \
      -H 'content-type: application/x-www-form-urlencoded' \
      -d 'username=john&password=123456'
    

    然后像这样称呼它:

    access_token

    这应该给出与上面类似的回应。

    您现在可以提供此Authorization: Bearer access_token_should_go_here标题curl -X GET \ http://localhost:51689/api/values \ -H 'authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjczODhkMjY0MDg4Y2NjOGRiZTcwODIzZGIxYzY3ZWNkIiwidHlwIjoiSldUIn0.eyJuYmYiOjE1MDUwODIyODQsImV4cCI6MTUwNTA4NTg4NCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MTY4OSIsImF1ZCI6WyJodHRwOi8vbG9jYWxob3N0OjUxNjg5L3Jlc291cmNlcyIsIk15QXBpIl0sImNsaWVudF9pZCI6ImFwaWNsaWVudGlkIiwic3ViIjoic29tZS11bmlxdWUtaWQtMTIzNDU2Nzg5ODAiLCJhdXRoX3RpbWUiOjE1MDUwODIyODQsImlkcCI6ImxvY2FsIiwic2NvcGUiOlsibXlhcGkiXSwiYW1yIjpbInB3ZCJdfQ.hQ60zzEbZOSVpP54yGAnnzfVEks18YXn3gU2wfFgNB33UxQabk1l3xkaeUPTpuFdmFTm4TbVatPaziGqaxjzYgfdVoAwQ3rYJMuYzOh0kUowKxXTkquAlD13ScpvxrGeCXGxFTRHrxX2h-1hHGQ9j2y2f3-ESynzrCdxp5HEH1271BSYfQ7pZIzvyxxpbmOzzKDzdYfcJV6ocnOU4jXBhw6iOzqpR03zxxtjIjGbJd2QwWklBGqZlO_thdZZFi-t7zu5eC4wqRCYGGZYWOUC17_Btc_Irg2SsvLCUDzsaBw7AVgLpZ7YjF-RsVqIi6oxNQ2K0zllzUy8VbupbWKr5Q' \ -H 'cache-control: no-cache' \ ,如下所示:

    [Authorize]

    现在你应该超越AddJwtBearer属性。耶!

    您现在拥有一个 Web应用程序,它既可以作为Auth服务器,也可以作为资源服务器。

    有趣的事实:通过上面的示例,Authority选项将应用程序自己的网址指定为.form-control { height: auto; min-height: 36px; } ,从而使应用程序请求自己使用公钥来验证令牌。您也可以使用代码直接将此密钥提供给身份验证中间件。