入门教程:.NET开源OpenID Connect 和OAuth解决方案IdentityServer v3 创建简单的OAuth2.0服务器,客户端和API(三)
本教程的目的在于创造尽可能简单的identityserver安装作为一个oauth2授权服务器。这应该能够让你了解一些基本功能和配置选项(完整的源代码可以发现在这里)。在后面的文档中会介绍更多的高级功能。本教程包括:
创建一个自托管identityserver
设置为使用一个应用程序的帐户以及用户对通信应用的客户服务代表
注册一个API
请求访问令牌
调用API
验证一个访问令牌
创建一个授权服务器(IdentityServer3)
创建一个控制台应用程序,并且在程序包管理器控制台中输入
install-package identityserver3
注册API
API作为请求范围,您需要注册所有您希望能够请求访问令牌的所有API,然后我们创建一个类用于返回在这个作用范围内所有的API
using IdentityServer3.Core.Models; static class Scopes
{
public static List<Scope> Get()
{
return new List<Scope>
{
new Scope
{
Name = "api1"
}
};
}
}
注册客户端
现在我们要注册一个客户端。这个客户将能够申请api1 scope的资源。对于我们的第一次迭代,将有没有人参与,客户端将简单地要求代表自己的令牌(认为机器与机器通信)。
对于这个客户端,我们配置以下的东西:
显示名称和编号(唯一的名称)
客户端密钥
客户端凭据
使用所谓的引用标记。参考标记不需要签名证书。
允许访问的作用域("api1")
using IdentityServer3.Core.Models; static class Clients
{
public static List<Client> Get()
{
return new List<Client>
{
// no human involved
new Client
{
ClientName = "Silicon-only Client",
ClientId = "silicon",
Enabled = true,
AccessTokenType = AccessTokenType.Reference, Flow = Flows.ClientCredentials, ClientSecrets = new List<Secret>
{
new Secret("F621F470-9731-4A25-80EF-67A6F7C5F4B8".Sha256())
}, AllowedScopes = new List<string>
{
"api1"
}
}
};
}
}
配置 IdentityServer
identityserver作为OWIN的中间件的实现,它是通过UseIdentityServer扩展方法在Startup类中配置。
下面的代码配置一个使用我们之前定义的客户端个作用域的授权服务器,稍后我们会添加用户进来。
using Owin;
using System.Collections.Generic;
using IdentityServer3.Core.Configuration;
using IdentityServer3.Core.Services.InMemory; namespace IdSrv
{
class Startup
{
public void Configuration(IAppBuilder app)
{
var options = new IdentityServerOptions
{
Factory = new IdentityServerServiceFactory()
.UseInMemoryClients(Clients.Get())
.UseInMemoryScopes(Scopes.Get())
.UseInMemoryUsers(new List<InMemoryUser>()), RequireSsl = false
}; app.UseIdentityServer(options);
}
}
}
添加日志记录
因为我们在一个控制台中运行,它是非常方便的日志输出直接到控制台窗口。Serilog是一个很好的日志库
install-package serilog
install-package serilog.sinks.literate
托管 IdentityServer
最后一步是托管identityserver。在程序包管理控制台添加OWIN
install-package Microsoft.Owin.SelfHost
在Program.cs文件中添加一下代码:
// logging
Log.Logger = new LoggerConfiguration()
.WriteTo
.LiterateConsole(outputTemplate: "{Timestamp:HH:MM} [{Level}] ({Name:l}){NewLine} {Message}{NewLine}{Exception}")
.CreateLogger(); // hosting identityserver
using (WebApp.Start<Startup>("http://localhost:5000"))
{
Console.WriteLine("server running...");
Console.ReadLine();
}
然后当你启动控制台程序的时候你会看到控制台输出“server running...”
添加一个 API
在这一部分中我们将添加一个简单的Web API,我们只需要从identityserver设置一个访问令牌。
创建API应用程序
在的解决方案中添加一个新的ASP.NET Web API 应用程序,选择空模板
添加必要的NuGet包:
install-package Microsoft.Owin.Host.SystemWeb
install-package Microsoft.AspNet.WebApi.Owin
install-package IdentityServer3.AccessTokenValidation
添加Controller
添加这个简单的测试控制器:
[Route("test")]
public class TestController : ApiController
{
public IHttpActionResult Get()
{
var caller = User as ClaimsPrincipal; return Json(new
{
message = "OK computer",
client = caller.FindFirst("client_id").Value
});
}
}
控制器上的用户属性让您从访问令牌中访问该请求的权限。
添加Startup
添加以下Startup.cs为建立Web API和identityserver配置信任启动类
using IdentityServer3.AccessTokenValidation; public void Configuration(IAppBuilder app)
{
// accept access tokens from identityserver and require a scope of 'api1'
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "http://localhost:5000",
ValidationMode = ValidationMode.ValidationEndpoint, RequiredScopes = new[] { "api1" }
}); // configure web api
var config = new HttpConfiguration();
config.MapHttpAttributeRoutes(); // require authentication for all controllers
config.Filters.Add(new AuthorizeAttribute()); app.UseWebApi(config);
}
试着打开浏览器,访问测试控制器-你应该看到一个401,因为必要的访问令牌丢失。
添加Console客户端
在下一部分中,我们将添加一个简单的控制台客户端,该客户端将请求访问令牌,并使用该接口进行身份验证。
首先添加一个新的控制台项目并安装一oauth2客户端需要的NuGet包:
install-package IdentityModel
第一段代码 获取客户端Token使用客户端证书:
using IdentityModel.Client; static TokenResponse GetClientToken()
{
var client = new TokenClient(
"http://localhost:5000/connect/token",
"silicon",
"F621F470-9731-4A25-80EF-67A6F7C5F4B8"); return client.RequestClientCredentialsAsync("api1").Result;
}
第二段代码 使用访问令牌调用API:
static void CallApi(TokenResponse response)
{
var client = new HttpClient();
client.SetBearerToken(response.AccessToken); Console.WriteLine(client.GetStringAsync("http://localhost:14869/test").Result);
}
如果你启动控制台程序,你应该看到{"message":"OK computer","client":"silicon"}在您的控制台。
添加一个用户
到目前为止,客户端请求一个访问令牌本身,没有用户参与。让我们介绍一个人。
添加一个获取用户的服务
用户服务管理用户-对于这个示例,我们将使用简单的内存用户服务。首先我们需要定义一些用户:
using IdentityServer3.Core.Services.InMemory; static class Users
{
public static List<InMemoryUser> Get()
{
return new List<InMemoryUser>
{
new InMemoryUser
{
Username = "bob",
Password = "secret",
Subject = ""
},
new InMemoryUser
{
Username = "alice",
Password = "secret",
Subject = ""
}
};
}
}
用户名和密码被用来验证用户,subject是该用户将被嵌入到访问令牌的唯一标识符。使用Users.Get()替换Startup.cs中的new List<InMemoryUser>()
添加一个客户端
接下来,我们将添加一个客户定义,使用流称为资源所有者的密码证书授予。此流程允许客户端将用户的用户名和密码发送到令牌服务,并在返回中获取访问令牌。
using IdentityServer3.Core.Models;
using System.Collections.Generic; namespace IdSrv
{
static class Clients
{
public static List<Client> Get()
{
return new List<Client>
{
// no human involved
new Client
{
ClientName = "Silicon-only Client",
ClientId = "silicon",
Enabled = true,
AccessTokenType = AccessTokenType.Reference, Flow = Flows.ClientCredentials, ClientSecrets = new List<Secret>
{
new Secret("F621F470-9731-4A25-80EF-67A6F7C5F4B8".Sha256())
}, AllowedScopes = new List<string>
{
"api1"
}
}, // human is involved
new Client
{
ClientName = "Silicon on behalf of Carbon Client",
ClientId = "carbon",
Enabled = true,
AccessTokenType = AccessTokenType.Reference, Flow = Flows.ResourceOwner, ClientSecrets = new List<Secret>
{
new Secret("21B5F798-BE55-42BC-8AA8-0025B903DC3B".Sha256())
}, AllowedScopes = new List<string>
{
"api1"
}
}
};
}
}
}
更新API
当涉及到人的时候,访问令牌将包含子请求以唯一标识用户。让我们对API的控制器做小的修改,:
[Route("test")]
public class TestController : ApiController
{
public IHttpActionResult Get()
{
var caller = User as ClaimsPrincipal; var subjectClaim = caller.FindFirst("sub");
if (subjectClaim != null)
{
return Json(new
{
message = "OK user",
client = caller.FindFirst("client_id").Value,
subject = subjectClaim.Value
});
}
else
{
return Json(new
{
message = "OK computer",
client = caller.FindFirst("client_id").Value
});
}
}
}
更新客户端
下一个向客户端添加一个新的方法,代表用户请求访问令牌:
static TokenResponse GetUserToken()
{
var client = new TokenClient(
"http://localhost:5000/connect/token",
"carbon",
"21B5F798-BE55-42BC-8AA8-0025B903DC3B"); return client.RequestResourceOwnerPasswordAsync("bob", "secret", "api1").Result;
}
入门教程:.NET开源OpenID Connect 和OAuth解决方案IdentityServer v3 创建简单的OAuth2.0服务器,客户端和API(三)的更多相关文章
- 入门教程:.NET开源OpenID Connect 和OAuth解决方案IdentityServer v3 介绍 (一)
现代的应用程序看起来像这样: 典型的交互操作包括: 浏览器与 web 应用程序进行通信 Web 应用程序与 web Api (有时是在他们自己的有时代表用户) 通信 基于浏览器的应用程序与 web A ...
- 入门教程:.NET开源OpenID Connect 和OAuth解决方案IdentityServer v3 术语(二)
你应该知道的在文档和对象模型中使用一些特定的术语: OpenID Connect Provider (OP) 授权服务器 Thinktecture IdentityServer v3 是一个.NET ...
- 一个功能完备的.NET开源OpenID Connect/OAuth 2.0框架——IdentityServer3
今天推荐的是我一直以来都在关注的一个开源的OpenID Connect/OAuth 2.0服务框架--IdentityServer3.其支持完整的OpenID Connect/OAuth 2.0标准, ...
- IdentityServer4 实现 OpenID Connect 和 OAuth 2.0
关于 OAuth 2.0 的相关内容,点击查看:ASP.NET WebApi OWIN 实现 OAuth 2.0 OpenID 是一个去中心化的网上身份认证系统.对于支持 OpenID 的网站,用户不 ...
- IdentityServer4 中文文档 -11- (快速入门)添加基于 OpenID Connect 的用户认证
IdentityServer4 中文文档 -11- (快速入门)添加基于 OpenID Connect 的用户认证 原文:http://docs.identityserver.io/en/releas ...
- OpenID Connect:OAuth 2.0协议之上的简单身份层
OpenID Connect是什么?OpenID Connect(目前版本是1.0)是OAuth 2.0协议(可参考本人此篇:OAuth 2.0 / RCF6749 协议解读)之上的简单身份层,用 A ...
- IdentityServer4专题之五:OpenID Connect及其Client Credentials流程模式
1.基于概念 OAuth2.0与身份认证协议的角色映射 OpenID Connect 这个协议是2014颁发的,基于OAuth2.0,在这个协议中,ID Token会和Access Token一起发回 ...
- 使用 IdentityServer4 实现 OAuth 2.0 与 OpenID Connect 服务
IdentityServer4 是 ASP.NET Core 的一个包含 OIDC 和 OAuth 2.0 协议的框架.最近的关注点在 ABP 上,默认 ABP 也集成 IdentityServer4 ...
- Identity Server 4 预备知识 -- OpenID Connect 简介
我之前的文章简单的介绍了OAuth 2.0 (在这里: https://www.cnblogs.com/cgzl/p/9221488.html), 还不是很全. 这篇文章我要介绍一下 OpenID C ...
随机推荐
- c++用vector创建二维数组
1 vector二维数组的创建和初始化 std::vector <int> vec(10,90); //将10个一维动态数组初始为90std::vector<std::vector& ...
- 创建自己的java类库并加以调用方法
第一次搞博客,心里有点发慌,记录一下:2018/2/1/ 21:33 今天Think In Java第4版 中文版(英文看着可能很耗时),看到了6.1.3 定制工具库这一章节,之前作者调用自己的类 ...
- "零代码”开发B/S企业管理软件之一 :怎么创建数据库表
声明:该软件为本人原创作品,多年来一直在使用该软件做项目,软件本身也一直在改善,在增加新的功能.但一个人总是会有很多考虑不周全的地方,希望能找到做同类软件的同行一起探讨. 本人文笔不行,能把意思表达清 ...
- MySQL数据库(5)- pymysql的使用、索引
一.pymysql模块的使用 1.pymysql的下载和使用 之前我们都是通过MySQL自带的命令行客户端工具mysql来操作数据库,那如何在python程序中操作数据库呢?这就需要用到pymysql ...
- Python中的不同进制的语法和转换
不同进制的书写方式 八进制(Octal) 0o377 十六进制(Hex) 0xFF 二进制(Binary) 0b11111111 不同进制之间的转换 python提供了三个内置的函数,能够用来在不同进 ...
- SQL CHECK sql server免费监控单实例工具
SQL Check 阅读目录 SQL Check? 主要特点 说说不足 下载地址 小结 一款实时性能监测工具 回到目录 SQL Check? 一款实时监测SQL数据库性能.实时排查的问题的免费工具. ...
- oracle 禁用索引
同步数据的时候 有索引会比较慢 可以暂时禁用索引 --禁用索引 ALTER INDEX PK_T_AUTH_USERROLE_ID UNUSABLE; --恢复索引ALTER INDEX UK_T_A ...
- JS连等赋值的坑
cnblogs标题: JS连等赋值的坑 关于JS连等赋值有个经典的笔试题: var a = {n: 1}; var b = a; a.x = a = {n: 2}; console.log(a.x); ...
- python中self cls init的理解
原创文章,未经允许禁止转载! python中self cls init的理解 python中self cls init的理解
- 基于WinIO 3.0实现驱动级键盘模拟输入
基于WinIO 3.0实现驱动级键盘模拟输入 一个业务场景需要使用驱动级的键盘模拟,折腾了2天,总结一下,为后人节省时间. 限制条件: 1.需要真实PC机,虚拟机不行 2.仅支持PS/2 键盘(指外接 ...