github:https://github.com/IdentityServer/IdentityServer3/
documentation:https://identityserver.github.io/Documentation/
samples https://github.com/IdentityServer/IdentityServer3.Samples/

OAuth 2.0定义的四种授权方式。

  • 授权码模式(authorization code)
  • 简化模式(implicit)
  • 密码模式(resource owner password credentials)
  • 客户端模式(client credentials)

虽然之前已经基于 Katana 实现了 OAuth 2.0 的相关模式,后面发现 IdentityServer 要相对完善一些,IdentityServer 是属于 .NET Foundation 的一个子项目,IdentityServer3 是基于 Katana 开发的 OpenID Connect/OAuth 2.0 服务框架,虽然 Katana 微软已经不维护了,现已经属于 ASP.NET Core 的一部分,相应对应 ASP.NET Core 的版本是 IdentityServer4 ,还处于 Beta 版本;不过 IdentityServer3 的扩展IdentityServer3.Integration.AspNetCore 支持 ASP.NET Core , 个人觉得 ASP.NET Core 设计很好,但是现在还不成熟,可能还需要等一段时间,所以选择了 IdentityServer3 。

授权角色

资源拥有者(resource owner):能授权访问受保护资源的一个实体,如新浪微博用户 irving;

资源服务器(resource server):存储受保护资源,客户端通过 access token 请求资源,资源服务器响应受保护资源给客户端;存储着用户 irving 的微博等信息。

授权服务器(authorization server):成功验证资源拥有者并获取授权之后,授权服务器颁发授权令牌(Access Token)给客户端。

客户端(client:如新浪微博第三方应用,也可以是它自己的官方应用;其本身不存储资源,而是资源拥有者授权通过后,使用它的授权(授权令牌)访问受保护资源,然后客户端把相应的数据展示出来。“客户端”术语不代表任何特定实现(如应用运行在一台服务器、桌面、手机或其他设备)。

Client Credentials Grant 模式只需要关注 授权服务器,资源服务器,客户端三个角色  具体:https://identityserver.github.io/Documentation/docsv2/overview/terminology.html

授权服务器

Install-Package IdentityServer3

服务配置

public class Startup
{
/// <summary>
/// 配置idsv授权服务
/// </summary>
/// <param name="app"></param>
public void Configuration(IAppBuilder app)
{
var opts = new IdentityServerOptions
{
SiteName = "Embedded OAuth2 Service",
EnableWelcomePage = true,
Factory = new IdentityServerServiceFactory()
.UseInMemoryClients(Clients.Get())
.UseInMemoryScopes(Scopes.Get())
.UseInMemoryUsers(new List<InMemoryUser>()),
//.UseInMemoryUsers(Users.Get())
RequireSsl = false,
//SigningCertificate = new X509Certificate2(string.Format(@"{0}\bin\identityServer\idsrv3test.pfx", AppDomain.CurrentDomain.BaseDirectory), "idsrv3test")
};
app.UseIdentityServer(opts); /*
//自定义路由
app.Map("/identity", idsrvApp =>
{
idsrvApp.UseIdentityServer(opts);
});
*/
}
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

客户端

public class Clients
{
public static List<Client> Get()
{
return new List<Client>
{
new Client
{
ClientName = "App接口服务",
ClientId = "app_test_id",
Enabled = true,
AccessTokenType = AccessTokenType.Reference,
Flow = Flows.ClientCredentials,
ClientSecrets = new List<Secret>
{
new Secret("F621F470-9731-4A25-80EF-67A6F7C5F4B8".Sha256())
},
AllowedScopes = new List<string>
{
"user",
"order"
}
}
};
}

作用域

public class Scopes
{
public static List<Scope> Get()
{
return new List<Scope>
{
new Scope
{
Name = "user"
},
new Scope
{
Name = "order"
}
};
}
}

用户(客户端模式不需要用户参与所以没有用户数据)

完成上述工作,服务端基础服务就完成了,访问 /.well-known/openid-configuration ,可以获得服务的配置信息,暂且部署到 http://192.168.210.165 服务器上,配置信息如下(官方也就有服务端的示例: https://github.com/IdentityServer/demo.identityserver.io

{

    "issuer": "http://192.168.210.165",
"jwks_uri": "http://192.168.210.165/.well-known/jwks",
"authorization_endpoint": "http://192.168.210.165/connect/authorize",
"token_endpoint": "http://192.168.210.165/connect/token",
"userinfo_endpoint": "http://192.168.210.165/connect/userinfo",
"end_session_endpoint": "http://192.168.210.165/connect/endsession",
"check_session_iframe": "http://192.168.210.165/connect/checksession",
"revocation_endpoint": "http://192.168.210.165/connect/revocation",
"introspection_endpoint": "http://192.168.210.165/connect/introspect",
"frontchannel_logout_supported": true,
"frontchannel_logout_session_supported": true,
"scopes_supported": [
"user",
"order"
],
"claims_supported": [ ],
"response_types_supported": [
"code",
"token",
"id_token",
"id_token token",
"code id_token",
"code token",
"code id_token token"
],
"response_modes_supported": [
"form_post",
"query",
"fragment"
],
"grant_types_supported": [
"authorization_code",
"client_credentials",
"password",
"refresh_token",
"implicit"
],
"subject_types_supported": [
"public"
],
"id_token_signing_alg_values_supported": [
"RS256"
],
"code_challenge_methods_supported": [
"plain",
"S256"
],
"token_endpoint_auth_methods_supported": [
"client_secret_post",
"client_secret_basic"
] }

注意:寄宿到 IIS 中需要 WebConfig 配置中需配置:

<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
</modules>
</system.webServer

资源服务器

Install-Package Microsoft.Owin.Host.SystemWeb

Install-Package Microsoft.AspNet.WebApi.Owin

Install-Package IdentityServer3.AccessTokenValidation

服务配置

public class Startup
{
/// <summary>
/// 配置授权服务
/// </summary>
/// <param name="app"></param>
public void Configuration(IAppBuilder app)
{
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "http://192.168.210.165",
ValidationMode = ValidationMode.ValidationEndpoint,
EnableValidationResultCache = true,
ValidationResultCacheDuration = TimeSpan.FromMinutes(5),
RequiredScopes = new[] { "user", "order" }
});
}
}

控制器

    [Route("api/v1/values")]
public class ValuesController : ApiController
{
public IHttpActionResult Get()
{
var caller = User as ClaimsPrincipal;
return Json(new
{
message = "OK computer",
client = caller.FindFirst("client_id").Value
});
}
}

OK,完成,由于是一台测试服务器,部署到 http://192.168.210.165:88/ 端口。

客户端

Install-Package serilog

Install-Package serilog.sinks.literate

Install-Package IdentityModel

class Program
{
static void Main(string[] args)
{
var log = new LoggerConfiguration()
.WriteTo
.LiterateConsole(outputTemplate: "{Timestamp:HH:mm} [{Level}] ({Name:l}){NewLine} {Message}{NewLine}{Exception}")
.CreateLogger();
var token = new TokenClient(
"http://192.168.210.165/connect/token",
"app_test_id",
"F621F470-9731-4A25-80EF-67A6F7C5F4B8");
var response = token.RequestClientCredentialsAsync("user").Result;
var client = new HttpClient();
client.SetBearerToken(response.AccessToken);
log.Information(client.GetStringAsync("http://192.168.210.165:88/api/v1/values").Result);
Console.ReadKey();
}
}

测试

顺便使用Fiddler抓了一下包

                POST http://192.168.210.165/connect/token HTTP/1.1
Accept: application/json
Authorization: Basic YXBwX3Rlc3RfaWQ6RjYyMUY0NzAtOTczMS00QTI1LTgwRUYtNjdBNkY3QzVGNEI4
Content-Type: application/x-www-form-urlencoded
Host: 192.168.210.165
Content-Length: 40
Expect: 100-continue
Connection: Keep-Alive grant_type=client_credentials&scope=user

                GET http://192.168.210.165:88/api/v1/values HTTP/1.1
Authorization: Bearer 9f82476751e1f8b93f1ea6df7de83b51
Host: 192.168.210.165:88

个人比较喜欢使用 Flurl.Http 这个类库,可以扩展一下客户端,扩展的方法现在还有一些问题,就不贴代码了。

其他细节

REFER:

Announcing IdentityServer for ASP.NET 5 and .NET Core

http://leastprivilege.com/2016/01/11/announcing-identityserver-for-asp-net-5-and-net-core/

OAuth2 Implicit Flow with Angular and ASP.NET Core 1.0 IdentityServer

http://damienbod.com/2015/11/08/oauth2-implicit-flow-with-angular-and-asp-net-5-identity-server

理解OAuth 2.0

http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html

基于 IdentityServer3 实现 OAuth 2.0 授权服务【客户端模式(Client Credentials Grant)】的更多相关文章

  1. 基于 IdentityServer3 实现 OAuth 2.0 授权服务【密码模式(Resource Owner Password Credentials)】

    密码模式(Resource Owner Password Credentials Grant)中,用户向客户端提供自己的用户名和密码.客户端使用这些信息,向"服务商提供商"索要授权 ...

  2. 基于 IdentityServer3 实现 OAuth 2.0 授权服务数据持久化

    最近花了一点时间,阅读了IdentityServer的源码,大致了解项目整体的抽象思维.面向对象的重要性; 生产环境如果要使用 IdentityServer3 ,主要涉及授权服务,资源服务的部署负载的 ...

  3. (转)基于OWIN WebAPI 使用OAuth授权服务【客户端模式(Client Credentials Grant)】

    适应范围 采用Client Credentials方式,即应用公钥.密钥方式获取Access Token,适用于任何类型应用,但通过它所获取的Access Token只能用于访问与用户无关的Open ...

  4. 基于OWIN WebAPI 使用OAuth授权服务【客户端模式(Client Credentials Grant)】

    适应范围 采用Client Credentials方式,即应用公钥.密钥方式获取Access Token,适用于任何类型应用,但通过它所获取的Access Token只能用于访问与用户无关的Open ...

  5. Microsoft.Owin.Security.OAuth搭建OAuth2.0授权服务端

    Microsoft.Owin.Security.OAuth搭建OAuth2.0授权服务端 目录 前言 OAuth2.0简介 授权模式 (SimpleSSO示例) 使用Microsoft.Owin.Se ...

  6. SimpleSSO:使用Microsoft.Owin.Security.OAuth搭建OAuth2.0授权服务端

    目录 前言 OAuth2.0简介 授权模式 (SimpleSSO示例) 使用Microsoft.Owin.Security.SimpleSSO模拟OpenID认证 通过authorization co ...

  7. 理解OAuth 2.0授权

    一.什么是OAuth 二.什么场景下会用到OAuth授权 三.OAuth 2.0中的4个成员 四.OAuth 2.0授权流程 五.OAuth 2.0授权模式 1.    authorization c ...

  8. OAuth 2.0 授权认证详解

    一.认识 OAuth 2.0 1.1 OAuth 2.0 应用场景 OAuth 2.0 标准目前被广泛应用在第三方登录场景中,以下是虚拟出来的角色,阐述 OAuth2 能帮我们干什么,引用阮一峰这篇理 ...

  9. 在ASP.NET中基于Owin OAuth使用Client Credentials Grant授权发放Token

    OAuth真是一个复杂的东东,即使你把OAuth规范倒背如流,在具体实现时也会无从下手.因此,Microsoft.Owin.Security.OAuth应运而生(它的实现代码在Katana项目中),帮 ...

随机推荐

  1. 关于php Hash算法的一些整理总结

    最近在公司内部的分享交流会上,有幸听到了鸟哥的关于php底层的一些算法的分享,虽然当时有些问题没有特别的明白,但是会后,查阅了各种各样的相关资料,对php的一些核心的hash算法有了进一步的理解和认识 ...

  2. MFC坐标空间与映射模式

    逻辑坐标:使用GDI绘图时使用的坐标系 设备坐标系:实际设备(显示器.打印机)的坐标系,即我们实际看到的坐标系. 坐标空间 在Windows NT/2000中Win32 API中支持以下四层坐标空间: ...

  3. mysql 不允许连接

    错误提示: ERROR 1130: Host '192.168.1.1' is not allowed to connect to this MySQL server的解决方法: 1.改表法.可能是你 ...

  4. oracle全文检索

    全文检索 oracle对使用几十万以上的数据进行like模糊查询速度极差,包括 like 'AAA%' ,like '%AAA',like '%AAA%',like '%A%A%'的那些模糊查询.网上 ...

  5. linux shell 去掉文本处理中的双引号

    cat aa.txt |sed 's/\"//g'  结果是:hello aa.txt "hello"

  6. C#控件根据窗体改变大小

    using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...

  7. iOS 拨打电话三种方法

    小弟查了很多地方的关于iOS程序拨打电话,大都不全,今天我总结了三种方法,各有不同,拿来给大家分享,希望给大家有所帮助1,这种方法,拨打完电话回不到原来的应用,会停留在通讯录里,而且是直接拨打,不弹出 ...

  8. 设置h5页面不可复制文字

    * { moz-user-select: -moz-none; -moz-user-select: none; -o-user-select: none; -khtml-user-select: no ...

  9. Data Base MongoDB 无法创建抽象类的问题,

     无法创建抽象类BsonClassMap.RegisterClassMap 大家都知道抽象类是无法实例化的,即:不能new. 在以下这些情况会遇到这种问题: 1.基类是抽象类: 2.基类是接口: 由于 ...

  10. Eclipse: Launch failed. Binary not found

    最近写demo出现这个问题, 然后上网搜了一会儿, 最后发现只要点击eclipse上的锤子图标就可以了.