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. javaweb学习第一天 debug

    debug 断点: f5:step into f6:step over f7:step return drop to frame:跳到当前方法的的第一行 resume:跳到下一个断点 watch:观察 ...

  2. Egret中的对象池ObjectPool

    为了可以让对象复用,防止大量重复创建对象,导致资源浪费,使用对象池来管理. 对象池具体含义作用,自行百度. 一 对象池A 二 对象池B 三 字符串key和对象key的效率 一 对象池A /** * 对 ...

  3. Windows 7 下如何设置机器级别的DCOM权限

    Windows 7 下如何设置机器级别的DCOM权限 To grant Remote Activation permissions to the SMS Admins group From the S ...

  4. ecshop 商品页面添加商品标签:

    /* @脚垫客户 需要给商品加属性.最简单粗暴的办法.后台调用加入.界面没有美化. */ goods.dwt <ul class="quantity"> <h2& ...

  5. vc 中调用COM组件的方法

    需求:1.创建myCom.dll,该COM只有一个组件,两个接口:   IGetRes--方法Hello(),   IGetResEx--方法HelloEx() 2.在工程中导入组件或类型库  #im ...

  6. 循序渐进Python3(六) -- 初识内置变量、反射、递归

    #python用下划线作为变量前缀和后缀指定特殊变量.稍后我们会发现,   #对于程序来说,其中的有些变量是非常有用的,而其他的则是未知或者无用的.   #我们总结一下Python中下划线的特殊用法  ...

  7. 基于weka的文本分类实现

    weka介绍 参见 1)百度百科:http://baike.baidu.com/link?url=V9GKiFxiAoFkaUvPULJ7gK_xoEDnSfUNR1woed0YTmo20Wjo0wY ...

  8. 【转】进程与CPU

    声明:本博客转自:http://blog.chinaunix.net/uid-20737871-id-1881246.html 简单地说,CPU 亲和性(affinity) 就是进程要在某个给定的 C ...

  9. mybatis 打印sql 语句

    拦截器 package com.cares.asis.mybatis.interceptor; import java.text.DateFormat; import java.util.Date; ...

  10. 表A的数据减去表B ,最终得到表C

    ==========表A数据如下:                 表B数据如下:cr     zc     lx                     cr    zc    lx100   10 ...