使用ResourceOwnerPassword流程来保护API

OAuth2.0中的ResourceOwnerPassword授权流程允许一个客户端发送username和password到token服务上面,以便获取一个代表用户的access token。

”规范“中建议只对受信任的客户端使用这种授权类型。通常情况来讲,在有用户交互的场景下,你应该优先使用OpenID Connect协议中的其中一个流程(有authorization code 、implicit、hybrid)来对用户进行认证,并获取access token。

话虽如此,这种授权类型引入了IdentityServer中的用户的概念,这也是我们要展现它的唯一原因。

添加用户

就像内存中的资源(或者叫做scopes)和客户端,也可以创建内存中的用户。

TestUser类代表了一个测试用户和它的一些声明(claim)。我们现在在Config类中创建一些用户:

using IdentityServer4.Test;

public static List<TestUser> GetUsers()
{
    return new List<TestUser>
    {
        new TestUser
        {
            SubjectId = ",
            Username = "alice",
            Password = "password"
        },
        new TestUser
        {
            SubjectId = ",
            Username = "bob",
            Password = "password"
        }
    };
}

然后在ConfigureService方法中注入:

public void ConfigureServices(IServiceCollection services)
{
    // configure identity server with in-memory stores, keys, clients and scopes
    services.AddIdentityServer()
        .AddDeveloperSigningCredential()
        .AddInMemoryApiResources(Config.GetApiResources())
        .AddInMemoryClients(Config.GetClients())
        .AddTestUsers(Config.GetUsers());
}

AddTestUsers扩展方法在后台做了这么几件事:

  • 添加了对resource owner password这种授权类型的支持
  • 添加了通常在login ui中使用的用户相关的服务。
  • 在testuser上添加了profile service。

为resource owner password这种授权类型创建一个相应的客户端

如果你想要客户端对于这两种授权类型都支持,你可以在现有的客户端上面通过修改AllowedGrantTypes属性的值来添加对这种授权类型的支持。

通常情况下你只是想要创建一个单独的客户端作为resource owner password这种授权类型的场景下使用,在Config类的GetClients方法中添加以下的代码:

public static IEnumerable<Client> GetClients()
{
    return new List<Client>
    {
        // other clients omitted...

        // resource owner password grant client
        new Client
        {
            ClientId = "ro.client",
            AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,

            ClientSecrets =
            {
                new Secret("secret".Sha256())
            },
            AllowedScopes = { "api1" }
        }
    };
}

使用password的授权类型来请求token

上面定义的那个客户端看起来和我们先前定义的client credentials客户端看起来很像。最主要的不同在于现在客户端会收集用户的密码,并在请求token的过程中将他连同其他东西一起发送到token service上面。

再次使用IdentityModel的TokenCLient来帮助我们实现这个请求:

// request token
var tokenClient = new TokenClient(disco.TokenEndpoint, "ro.client", "secret");
var tokenResponse = await tokenClient.RequestResourceOwnerPasswordAsync("alice", "password", "api1");

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

Console.WriteLine(tokenResponse.Json);
Console.WriteLine("\n\n");

当你向API发送token的时候,你会发现一个非常小而又非常重要的改变(相对于clientcredential这种授权类型来说):access token现在包含了一个”sub“的claim,这个claim就是用的唯一标识(在Config类中定义的TestUser的subjectid属性就是这里的东西),这个不同会通过api的方法返回的json里面发现。我在这里展示1下,我通过postman:

首先是通过client credential这种授权获取的token来访问api的,获取的结果如下:

[
    {
        "claimType": "nbf",
        "
    },
    {
        "claimType": "exp",
        "
    },
    {
        "claimType": "iss",
        "claimValue": "http://localhost:5000"
    },
    {
        "claimType": "aud",
        "claimValue": "http://localhost:5000/resources"
    },
    {
        "claimType": "aud",
        "claimValue": "api1"
    },
    {
        "claimType": "client_id",
        "claimValue": "firstClient"
    },
    {
        "claimType": "scope",
        "claimValue": "api1"
    }
]

看一看出没有sub这个声明。

然后使用resource owner password这个授权类型来搞到token,再用这个token访问一下api:

[
    {
        "claimType": "nbf",
        "
    },
    {
        "claimType": "exp",
        "
    },
    {
        "claimType": "iss",
        "claimValue": "http://localhost:5000"
    },
    {
        "claimType": "aud",
        "claimValue": "http://localhost:5000/resources"
    },
    {
        "claimType": "aud",
        "claimValue": "api1"
    },
    {
        "claimType": "client_id",
        "claimValue": "secondClient"
    },
    {
        "claimType": "sub",
        "
    },
    {
        "claimType": "auth_time",
        "
    },
    {
        "claimType": "idp",
        "claimValue": "local"
    },
    {
        "claimType": "scope",
        "claimValue": "api1"
    },
    {
        "claimType": "amr",
        "claimValue": "pwd"
    }
]

IdentityServer4【QuickStart】之使用ResourceOwnerPassword流程来保护API的更多相关文章

  1. 【IdentityServer4文档】- 使用客户端凭据保护 API

    使用客户端凭据保护 API quickstart 介绍了使用 IdentityServer 保护 API 的最基本场景. 接下来的场景,我们将定义一个 API 和一个想要访问它的客户端. 客户端将在 ...

  2. IdentityServer4【QuickStart】之使用ClientCredentials流程保护API

    使用ClientCredentials流程保护API 这个示例展示了使用IdentityServer中保护APIs的最基本的场景. 在这个场景中我们会定义一个API和一个想要访问它的客户端.客户端会在 ...

  3. IdentityServer4 ASP.NET Core的OpenID Connect OAuth 2.0框架学习保护API

    IdentityServer4 ASP.NET Core的OpenID Connect OAuth 2.0框架学习之保护API. 使用IdentityServer4 来实现使用客户端凭据保护ASP.N ...

  4. IdentityServer4 中文文档 -9- (快速入门)使用客户端凭证保护API

    IdentityServer4 中文文档 -9- (快速入门)使用客户端凭证保护API 原文:http://docs.identityserver.io/en/release/quickstarts/ ...

  5. asp.net core系列 54 IS4用客户端凭据保护API

    一. 概述 本篇开始进入IS4实战学习,从第一个示例开始,该示例是 “使用客户端凭据保护API”,这是使用IdentityServer保护api的最基本场景.该示例涉及到三个项目包括:Identity ...

  6. ASP.NET Core的身份认证框架IdentityServer4(7)- 使用客户端证书控制API访问

    前言 今天(2017-9-8,写于9.8,今天才发布)一口气连续把最后几篇IdentityServer4相关理论全部翻译完了,终于可以进入写代码的过程了,比较累.目前官方的文档和Demo以及一些相关组 ...

  7. 用ASP.NET Core 2.1 建立规范的 REST API -- 保护API和其它

    本文介绍如何保护API,无需看前边文章也能明白吧. 预备知识: http://www.cnblogs.com/cgzl/p/9010978.html http://www.cnblogs.com/cg ...

  8. Identity Server 4 - Hybrid Flow - 保护API资源

    这个系列文章介绍的是Identity Server 4 的 Hybrid Flow, 前两篇文章介绍了如何保护MVC客户端, 本文介绍如何保护API资源. 保护MVC客户端的文章: https://w ...

  9. IdentityServer4(7)- 使用客户端认证控制API访问(客户端授权模式)

    一.前言 本文已更新到 .NET Core 2.2 本文包括后续的Demo都会放在github:https://github.com/stulzq/IdentityServer4.Samples (Q ...

随机推荐

  1. Several ports (8005, 8080, 8009) required by Tomcat v7.0 Server at localhost are already in use.解决办法

    Several ports (8005, 8080, 8009) required by Tomcat v7.0 Server at localhost are already in use. The ...

  2. 3D touch 静态、动态设置及进入APP的跳转方式

    申明Quick Action有两种方式:静态和动态 静态是在info.plist文件中申明,动态则是在代码中注册,系统支持两者同时存在. -系统限制每个app最多显示4个快捷图标,包括静态和动态 静态 ...

  3. DShow实现一个avi视频的播放(含有个人解释和注释)

    此项目为win32下的控制台C++代码(别忘记配置DShow库) // movie_test.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" ...

  4. dom 左右两侧得广告(兼容IE FF)

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  5. Why String is immutable in Java ?--reference

    String is an immutable class in Java. An immutable class is simply a class whose instances cannot be ...

  6. css案例学习之双斜角横线菜单

    效果 代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w ...

  7. Oracle VM VirtulBox 安装Ubuntu16.04

    曾经自己在电脑中检索到Ubuntu kylin 16-10.vmdk 后就通过. 这种方式就进行了新建. 后自己从http://www.gaofumei.net/linux-download/783. ...

  8. mac 下安装mongodb

    转载自https://segmentfault.com/a/1190000002547229 概念 MongoDB 是一个跨平台的,面向文档的数据库,提供高性能,高可用性和可扩展性方便. MongoD ...

  9. CDMA学习

    1.关于RC:http://www.mscbsc.com/askpro/question74915 2.CDMA知识要点:http://wenku.baidu.com/view/d4511442a89 ...

  10. Maven– HelloWorld实例

    Maven– HelloWorld实例 maven安装好后,可以通过HelloWorld项目来体验一下maven是如何构建项目的.Maven项目的核心是pom.xml(就像Ant的build.xml一 ...