本文为 Perfect 官方投稿,作者 Rocky,版权归原作者所有,未经作者同意,请勿转载。
原文地址:http://mp.weixin.qq.com/s/_p5oNEQkSZ_qTnHlM9xlEA
技术之路,共同进步,欢迎投稿、约稿,给文章纠错,请发送邮件至mobilehub@csdn.net。

GSSAPI / SPNEGO 是一个很有意思的互联网标准,可能习惯 OAuth 的新生代程序员都不是很熟悉,但是可能大家都不知道所有的 Windows 服务器、苹果的 Apple TV,以及常见的局域网内文件共享、以及银行的各种“盾”,其实都在默默地使用这个协议。

具体放在 HTTP 服务器上的时候,究竟这个协议在干什么呢?

其实很简单。比如,你希望把这个服务器放到公网上,但是希望只有真正授权的用户能够访问,而且授权不是一个简单的用户名密码;而且这个服务器的用户后台很复杂,你根本不想去动这些包含了上百万个用户账号的老服务器,该怎么办呢?答案当然是 SPNEGO。

SPNEGO 最显著的特点,就是用 Kerberos 去登录,你自己开发的服务器中根本就不需要包含任何关于登录的页面和后台数据库!!!唯一需要考虑的就是 ACL 安全访问控制列表——SPNEGO 交给你的,只有一个用户名,即通过 Kerberos 安全审查的用户名称,然后再自行核对一下该用户是否有权读取当前页面即可,就这么简单!Kerberos 会自动根据用户登录结果发放访问凭证,如果超时凭证就过期,所以用户会感觉在局域网内开发程序那样省事儿。麻省理工的技术不是吹的,对吧?

让我们看看 Perfect 官网的程序吧:

本项目为包含有 SPNEGO 功能的 Perfect 项目模板

本项目是基于 PerfectTemplate 服务器模板。如果您还不熟悉 PerfectTemplate,请最好先尝试一下。

编译指南

本项目使用 Swift 3.0.2 工具链,支持 Ubuntu 和 Mac OS X

Xcode 编译指南

如果您希望使用 Xcode 编译该项目,请确保将下列编译标识正确传递给 SPM 软件包管理器:

$ swift package -Xlinker -framework -Xlinker GSS generate-xcodeproj

Linux 编译指南

编译本项目之前请确保 libkrb5-dev 函数库已经正确安装。

$ sudo apt-get install libkrb5-dev

KDC 配置

请配置好您的应用服务器/etc/krb5.conf,以便于该服务器能够正常连接到目标的 KDC。请参考下面的例子,在这个例子中,应用服务器希望连接到控制区域 KRB5.CA,并且该控制区域的 KDC 控制中心域名为 nut.krb5.ca:

[realms]
KRB5.CA = {kdc = nut.krb5.caadmin_server = nut.krb5.ca
}
[domain_realm]
.krb5.ca = KRB5.CA
krb5.ca = KRB5.CA

准备 Kerberos 授权钥匙

下一步需要联系您的 KDC 管理员,获得应用服务器将使用的 keytab 钥匙文件。

参考下面的例子的示范配置,⚠️下列所有主机必须注册到同一个 DNS⚠️

  • KDC 安全控制中心服务器: nut.krb5.ca
  • 应用服务器: apple.krb5.ca
  • 应用服务器计划安装的协议类型: HTTP

如果处于上述环境,则 KDC 管理员需要登录 nut.krb5.ca 控制区域并采取下列操作:

kadmin.local: addprinc -randkey HTTP/apple.krb5.ca@KRB5.CA
kadmin.local: ktadd -k /tmp/krb5.keytab HTTP/apple.krb5.ca@KRB5.CA

生成钥匙文件 krb5.keytab 后,请将该钥匙安全地传输到您的应用服务器apple.krb5.ca并将文件移动到目录/etc下,然后赋予其适当权限,以便于您的服务器可以访问到。

编译和运行

运行下列命令可以编译本项目并在 8080 端口上启动包含 SPNEGO 机制的服务器。

git clone https://github.com/PerfectExamples/Perfect-SPNEGO-Demo.git
cd Perfect-SPNEGO-Demo
swift build
.build/debug/PerfectTemplate

可以看到服务器运行后的启动信息:

SPNEGO IS READY
[INFO] Starting HTTP server localhost on 0.0.0.0:8080

证明服务器已经准备好。

现在您可以尝试访问一下 http://apple.krb5.ca:8080 看看会发生什么事情。

如果您正在使用兼容 SPNEGO 的浏览器,那么可能会看到一个登录框,提示输入用户名密码。 或者,您可以使用下列命令行用于更清楚地理解整个验证过程:

$ kinit
$ curl -v --negotiate -u : http://apple.krb5.ca:8080

此时,应该可以注意到,如果没有使用 kinit 登录,则 curl 返回的是禁止访问。

URL 说明

请注意如果希望能够保证该范例能够正确运行,请使用 FQDN (完全限定域名) 来配置 URL 路径,而不是使用 localhost 或 IP 地址,并且服务器和客户端都需要配置为这种域名。

SPNEGO 验证过程

示范代码在原有 PerfectTemplate 基础上追加了几行程序,用于验证用户身份:

首先,接收到客户请求后,初始化了一个 SPNEGO 对象。 随后,处理器会将 HTTP 响应设置为 .unauthorized 表示需要授权,即指示客户端必须提供 SPNEGO 的有效凭证进行身份验证。 如果 HTTP 请求中已经包含了一个 Base64 编码的票据,那么服务器应该尝试使用这个方法接收票据并获取用户身份信息:let (username, reply_token) = try spnego.accept(base64Token: inputToken)

如果返回的用户名非空,则确认用户身份已经验证。此时您可能需要额外的 ACL(访问控制列表)进一步验证用户是否有权访问当前 URL 指向的资源,否则应该拒绝该请求。

请注意返回的另外一个参数 reply_token 如果非空,则需要发回给客户端以完成整个验证过程。

import PerfectSPNEGO
import Darwin
// 注意,主机名必须是完全限制名称 FQDN,并且已经在 KDC 上注册登记并获取合法 keytab 文件。
let hostname = "apple.krb5.ca"// 收到安全保护的请求处理器func handler(data: [String:Any]) throws -> RequestHandler {  return {request, response in    // 首先将返回状态设置为禁止访问response.status = .unauthorized// 服务器和客户机时间必须同步,因此返回一个 GMT 时间response.setHeader(.date, value: GMTNow())    // 提示客户机必须进行协议协商    response.setHeader(.wwwAuthenticate, value: "Negotiate")response.setHeader(.contentType, value: "text/html")    // 如果客户机无有效凭证则拒绝访问    guard let auth = request.header(.custom(name: "Authorization")) else {response.appendBody(string: "<html><H1>ACCESS DENIED</H1></html>\n")response.completed()      return}//end auth// 从客户机请求中提取身份验证票据凭证    let negotiate = "Negotiate "guard auth.hasPrefix(negotiate) else {response.appendBody(string: "<html><H1>INVALID TOKEN FORMAT</H1></html>\n")response.completed()      return}//end auth.prefix// 将凭证转化为标准格式    let inputToken = String(auth.characters.dropFirst(negotiate.utf8.count))    do {      let spnego = try Spnego("HTTP@\(hostname)")      // 尝试接收申请      let (username, outputToken) = try spnego.accept(base64Token: inputToken)      // 检查服务器是否需要返回收条      if let reply = outputToken {response.setHeader(.custom(name: "Authorization"), value:"Negotiate \(reply)")}//end if// 检查是否已经完成身份验证      if let user = username {        // 用户登录已经成功        // 注意,在生产服务器中,您可能需要进一步使用 ACL 安全访问列表来检查已验证身份的用户是否有足够的权限访问当前 URL 资源        response.status = .accepted// 返回受保护的资源内容        response.appendBody(string: "<html><title>Hello, world!</title><body>Welcome, \(user)</body></html>\n")}else {        // 验证失败,有可能是 DNS 错误造成,请务必使用 FQDN 完全限制域名        response.appendBody(string: "<html><H1>GSS REQUEST TO CALL IT ONCE MORE</H1></html>\n")}//end if    }catch (let err) {      // 用户身份验证失败      response.appendBody(string: "<html><H1>AUTHENTICATION FAILED: \(err)</H1></html>\n")}//end du// 完成身份验证    response.completed()}
}

了解最新移动开发、VR/AR 干货技术分享,请关注 mobilehub 微信公众号(ID: mobilehub)。

如何使用 Perfect-SPNEGO 保护你的服务器?相关推荐

  1. 星界边境服务器Linux,星界边境 保护与密码锁 服务器插件Mod

    星界边境 保护与密码锁 服务器插件Mod 这坑爹货你们用过吧?简直就是一个开关没实际价值! 服务器装了这个mod后,即使你没装你也能在服里让它拥有保护效果! 当然你也可以把它扔给好友一起享受保护的乐趣 ...

  2. 针对服务器操作系统安全,浅谈等级保护中的服务器操作系统安全

    服务器操作系统加固 现在信息系统中服务器上运行的主流操作系统基本上都是弱访问控制,操作系统管理员一权独大,没有相关的审计措施与权限制约,不能满足等级保护安全标记保护级三级的要求.现在向大家介绍一种服务 ...

  3. 服务器应用安全措施_建议的安全措施来保护您的服务器

    服务器应用安全措施 介绍 (Introduction) Getting your applications up and running will often be your primary conc ...

  4. 网络安全之小技巧保护(IIS)Web服务器

    <script type="text/javascript"></script> <script type="text/javascript ...

  5. 本网站受海外服务器保护,该网站服务器受美国保护

    该网站服务器受美国保护 乌和安 485万字 58人读过 全本 裴度,字中立,河东闻喜人.擢进士第.进御史中丞.宣徽五坊小使方秋阅鹰狗,所过挠官司,厚得饷谢乃去.下邽令裴寰,才吏也,不为礼,因构寰出丑言 ...

  6. 服务器安全狗系统漏洞修得未修复,服务器安全狗V2.2实测:更智能更灵活地保护您的服务器安全...

    安全狗工作室官方消息,最新版本服务器安全狗V2.2 beta1.0已在7月21号正式发布.笔者通过私人途径,获得新版安全狗发布之前的实测机会.闲话未几说,让我们一起来见识下新版服务器安全狗V2.2 b ...

  7. exchange系列(四)如何保护exchange邮件服务器的安全

    博主QQ:819594300 博客地址:http://zpf666.blog.51cto.com/ 有什么疑问的朋友可以联系博主,博主会帮你们解答,谢谢支持 理论部分: 邮件病毒的危害 窃取邮件内容 ...

  8. 从Banner入手保护linux系统服务器

    一,ftp服务Banner修改法:      wu-ftp修改    用十六进制文本编辑器修改/usr/sbin/in.ftpd文件,找到如下几行:     /var/log/lastlog     ...

  9. okta使用_使用Okta的单点登录保护您的Vert.x服务器

    okta使用 "我喜欢编写身份验证和授权代码." 〜从来没有Java开发人员. 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验 ...

最新文章

  1. 公司Joomla项目笔记1
  2. 大话中文文本分类之TextRNN_ATT
  3. 第十一届河南省赛--H : Attack City and Capture Territory
  4. 使用python的openpyxl模块操作excel
  5. C++(STL):28 ---关联式容器map用法
  6. GitHub使用教程-官网指南
  7. RPC规范接口实现模块Flask-JSONRPC
  8. 数据库学习——SQL之SELECT查询语句
  9. Get几个小技能——悬浮音乐播放器、字体压缩和打印效果
  10. 组策略 禁止用户策略下发到指定计算机,Win7 64位旗舰版下利用组策略禁止程序运行的设置技巧...
  11. (基于matlab)蒙特卡罗法 之 布丰投针实验 (1/10)
  12. 超低延时行情系统的设计方案及实现方案
  13. 宋登高 php,HDwiki百科建站第一期
  14. MCE公司:M525-针对混合谱系白血病(MLL)的新型抑制剂
  15. 政府运用大数据 决策告别“拍脑袋”
  16. awesomium --ExecuteJavascriptWithResult 执行异常
  17. 多谐振荡器构成的PWM发生器
  18. L32.linux命令每日一练 -- 第五章 Linux信息显示与搜索文件命令 -- dmesg和stat
  19. 利用Swing和GUI的相关知识,设计并编程实现一个GUI简易计算器
  20. xp系统终极瘦身大全

热门文章

  1. 小程序-记一次二进制文档流文件下载功能;
  2. oracle+m10-5,pchm10是oppo什么型号
  3. python电商项目-首页广告展示
  4. 高斯分布和正态分布有什么区别?Gaussian VS Normal
  5. 凌动x7可以用linux吗,英特尔凌动x7-Z8700性能跑分评测 | ZMMOO
  6. 互相关函数实现(c语言完整工程,利用cmake编译)
  7. Python-FCL 学习
  8. (1)C#与.NET Framework、FCL与CLR
  9. 关于 ECharts4 新增的数据集(dataset)
  10. 请不要关闭计算机电源正在,电脑关机时一直显示请不要关闭计算机正在更新安装,可以强制关机吗?...