搜索词>>iphone se2 耗时0.0030
  • iphone se2 运行内存多大

    最近苹果发布了一款新机 Iphone SE 二代最近苹果发布了一款新机 Iphone SE 二代。之前一直在猜测内存可能是3G.。通过一些软件,我们可以查询到确实如下:​​机器太新,很多检测APP还没上数据(或者说这款APP大多数数据靠手动录入的,假检查软件)
  • HTTP协议2.0_HTTP2.0新特性

    HTTP协议2.0,HTTP 2.0如何升级_HTTP2.0新特性_HTTP2.0详解。<h2>引用</h2>   本文主要讲述HTTP协议2.0版本,以及<a rel="external nofollow" target="_blank" id="http2.0" name="http2.0">HTTP协议2.0</a>的新特性说明 <h2>一.开篇HTTP发展的心路历程</h2> <br /> <img alt="开篇HTTP发展的心路历程,1" class="img-thumbnail" src="/assist/images/blog/76f5c3db6d6843809b1f42d62f0f8a6d.png" /><br /> 上图:连接无法复用<br /> <img alt="HTTP 协议 订单流程" class="img-thumbnail" src="/assist/images/blog/e77a5ee7ca904be584f248722782ccfb.png" /><br /> 上图:设置Connection:Keep-Alive,保持连接在一段时间内不断开。<br /> <img alt="HTTP协议多个订单" class="img-thumbnail" src="/assist/images/blog/f260aa472f694465ba83da7498272ade.png" /><br /> 上图:HTTPpipelining:建立多个连接<br /> <img alt="HTTP多路复用" class="img-thumbnail" src="/assist/images/blog/af6c10458a3146fdb9bc4b8b0254deed.png" /><br /> 上图:多路复用 <h2>二.先对HTTP协议进行简单介绍</h2> <p>   1. HTTP协议 :Hyper Text Transfer Protocol(超文本传输协议),是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。</p> <p>    2. HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。</p> <p>   3. HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。</p> <p>   4. HTTP协议工作于客户端-服务端架构为上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息。<br /> <img alt="Http协议客户端和服务端" class="img-thumbnail" src="/assist/images/blog/bd2f47f787154d74a164ca4cdc3cb381.png" /></p> <h2>三.HTTP 协议的版本</h2> <ul> <li>HTTP 0.9作为HTTP协议的第一个版本。是非常弱的。请求(Request)只有一行,比如: GET www.leautolink.com</li> <li>HTTP1.0最早在网页中使用是在1996年,那个时候只是使用一些较为简单的网页上和网络请求上。</li> <li>HTTP1.1则在1999年才开始广泛应用于现在的各大浏览器网络请求中,同时HTTP1.1也是当前使用最为广泛的HTTP协议。</li> </ul> <img alt="HTTP协议版本" class="img-thumbnail" src="/assist/images/blog/be03a1e810d5455483dd40e6c644428e.png" /><br />   <p><strong>HTTP 1.1 做了哪些升级:</strong></p> <p> </p> <ul> <li> <p><strong>缓存处理</strong>,在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。</p> </li> <li> <p><strong>带宽优化及网络连接的使用</strong>,HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。</p> </li> <li> <p><strong>错误通知的管理</strong>,在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。</p> </li> <li> <p><strong>Host头处理</strong>,在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。</p> </li> <li> <p><strong>长连接</strong>,HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。</p> </li> </ul> <p><strong>如何建立连接(三次握手)</strong></p> <p>    HTTP 是基于 TCP 协议的,浏览器最快也要在第三次握手时才能捎带 HTTP 请求报文,达到真正的建立连接,但是这些连接无法复用会导致每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显,慢启动则对文件类大请求影响较大。</p> <ul> <li> <p><strong>第一次</strong><strong>握手:</strong>建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。</p> </li> <li> <p><strong>第二次握手:</strong>服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;</p> </li> <li> <p><strong>第三次握手:</strong>客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。</p> </li> </ul> <p><strong>完成三次握手,客户端与服务器开始传送数据。</strong></p> <img alt="HTTP协议三次握手流程图" class="img-thumbnail" src="/assist/images/blog/5891e7762d3843e8aaf04edf552f6930.png" /> <p><strong>如何关闭连接(四次挥手):</strong></p> <p> </p> <p>    由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。</p> <p> </p> <p>     TCP的连接的拆除需要发送四个包,因此称为<strong>四次挥手(four-way handshake)</strong>。客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。</p> <p> </p> <ol> <li> <p>客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送。 </p> </li> <li> <p>服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。 </p> </li> <li> <p>服务器B关闭与客户端A的连接,发送一个FIN给客户端A。 </p> </li> <li> <p>客户端A发回ACK报文确认,并将确认序号设置为收到序号加1。 <br /> <img alt="HTTP 第三次和第四次握手" class="img-thumbnail" src="/assist/images/blog/7314195885b54567bac1275375c419fe.png" /><br />  </p> </li> </ol> <p><strong>浏览器阻塞(HOL blocking):</strong></p> <p>   浏览器对于同一个域名,一般PC端浏览器会针对单个域名的server同时建立6~8个连接,手机端的连接数则一般控制在4~6个(这个根据浏览器内核不同可能会有所差异),超过浏览器最大连接数限制,后续请求就会被阻塞。</p> <h2>三.在讲HTTP/2之前我们先来说说SPDY</h2> <p>  SPDY协议是Google提出的基于传输控制协议(TCP)的应用层协议,通过压缩、多路复用和优先级来缩短加载时间。该协议是一种更加快速的内容传输协议,于2009 年年中发布。</p> <p>  GoogleChrome、MozillaFirefox以及Opera已默认开启SPDY。Google曾经称它的测试显示,页面载入提高了一倍。该协议是一种更加快速的内容传输协议。</p> <p><strong>SPDY协议设定的目标</strong></p> <p>    1. 页面加载时间(PLT,Page • Load Time)降低 50%;</p> <p>    2. 无需网站作者修改任何内容;</p> <p>    3. 最小化配置复杂度,无需变更网络基础设施;</p> <p>注:为了达到降低50% 页面加载时间的目标,SPDY 引入了一个新的二进制分帧数据层,以实现多向请求和响应、优先次序、最小化及消除不必要的网络延迟,目的是更有效地利用底层TCP 连接;</p> <h2>四.HTTP/2:SPDY的升级版</h2> <ul> <li> <p>HTTP-WG(HTTP Working Group)在2012 年初把HTTP 2.0提到了议事日程,吸取SPDY 的经验教训,并在此基础上制定官方标准。</p> </li> <li> <p>HTTP/2 的主要目标是改进传输性能,更有效地利用网络资源,实现低延迟和高吞吐量。从另一方面看,HTTP 的高层协议语义并不会因为这次版本升级而受影响。所有HTTP 首部、值,以及它们的使用场景都不会变。</p> </li> <li> <p>HTTP/2 致力于突破上一代标准众所周知的性能限制,但它也是对之前1.x 标准的扩展,而非替代。之所以要递增一个大版本到2.0,主要是因为它改变了客户端与服务器之间交换数据的方式</p> </li> </ul> <p><strong>HTTP/2 是如何提高效率呢?</strong></p> <p><strong>  二进制分帧:HTTP 2.0 的所有帧都采用二进制编码</strong></p> <ul> <li> <p><strong>帧</strong>:客户端与服务器通过交换帧来通信,帧是基于这个新协议通信的最小单位。</p> </li> <li> <p><strong>消息</strong>:是指逻辑上的 HTTP 消息,比如请求、响应等,由一或多个帧组成。</p> </li> <li> <p><strong>流</strong>:流是连接中的一个虚拟信道,可以承载双向的消息;每个流都有一个唯一的整数标识符(1、2…N);</p> </li> </ul> <img alt="HTTP 2.0连接" class="img-thumbnail" src="/assist/images/blog/f3e1405c2a1f43c3a8ef78325d360f3b.png" /> <p><strong>多路复用 (Multiplexing)</strong></p> <p>    多路复用允许同时通过单一的 HTTP/2 连接发起多重的请求-响应消息。有了新的分帧机制后,HTTP/2 不再依赖多个TCP 连接去实现多流并行了。每个数据流都拆分成很多互不依赖的帧,而这些帧可以交错(乱序发送),还可以分优先级。最后再在另一端把它们重新组合起来。HTTP 2.0 连接都是持久化的,而且客户端与服务器之间也只需要一个连接(<strong>每个域名一个连接</strong>)即可。 </p> <p> </p> <p><strong>请求优先级</strong></p> <ul> <li> <p>把HTTP 消息分解为很多独立的帧之后,就可以通过优化这些帧的交错和传输顺序,每个流都可以带有一个31 比特的优先值:0 表示最高优先级;2的31次方-1 表示最低优先级。</p> </li> <li> <p>服务器可以根据流的优先级,控制资源分配(CPU、内存、带宽),而在响应数据准备好之后,优先将最高优先级的帧发送给客户端。</p> </li> <li> <p>HTTP 2.0 一举解决了所有这些低效的问题:浏览器可以在发现资源时立即分派请求,指定每个流的优先级,让服务器决定最优的响应次序。这样请求就不必排队了,既节省了时间,也最大限度地利用了每个连接。</p> </li> </ul> <p> </p> <p><strong>header压缩</strong></p> <p>    HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP/2使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。</p> <p> </p> <p><strong>服务端推送</strong></p> <ul> <li> <p>服务器可以对一个客户端请求发送多个响应。服务器向客户端推送资源无需客户端明确地请求。</p> </li> <li> <p>HTTP 2.0 连接后,客户端与服务器交换SETTINGS 帧,借此可以限定双向并发的流的最大数量。</p> </li> <li> <p>所有推送的资源都遵守同源策略。换句话说,服务器不能随便将第三方资源推送给客户端,而必须是经过双方确认才行。</p> </li> <li> <p>服务器必须遵循请求- 响应的循环,只能借着对请求的响应推送资源</p> </li> </ul> <p> </p> <p><strong>服务器推送到底是什么?</strong></p> <p>    服务端推送能把客户端所需要的资源伴随着index.html一起发送到客户端,省去了客户端重复请求的步骤。正因为没有发起请求,建立连接等操作,所以静态资源通过服务端推送的方式可以极大地提升速度。</p> <p> </p> <p>普通的客户端请求过程:<br /> <img alt="普通客户端请求HTTP协议过程" class="img-thumbnail" src="/assist/images/blog/98d6549c4dfe4180a51242a61353286a.png" /><br />  </p> 服务端推送的过程:<br /> <img alt="服务端推送的过程" class="img-thumbnail" src="/assist/images/blog/b1ca4e63108a42b8a7f49454b948416f.png" /> <p><strong>HTTP/2的多路复用和HTTP1.1中的长连接复用有什么区别?</strong></p> <ul> <li> <p>HTTP/1.0 一次请求-响应,建立一个连接,用完关闭;每一个请求都要建立一个连接;</p> </li> <li> <p>HTTP/1.1 Pipeling解决方式为,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某请求超时等,后续请求只能被阻塞,毫无办法,也就是人们常说的线头阻塞;</p> </li> <li> <p>HTTP/2多个请求可同时在一个连接上并行执行。某个请求任务耗时严重,不会影响到其它连接的正常执行;<br /> <img alt="HTTP" class="img-thumbnail" src="/assist/images/blog/ab81f47df21b4aa7941fec0556dcb814.png" /><br />  </p> </li> </ul> <h2>五.如何应用到自己的项目里</h2> <p>  现有的任何网站和应用,无需做任何修改都可以在HTTP 2.0 上跑起来。不用为了利用HTTP 2.0 的好处而修改标记。HTTP 服务器必须运行HTTP 2.0 协议,但大部分用户都不会因此而受到影响。</p> <p>  如果你使用NGINX,只要在配置文件中启动相应的协议就可以了,可以参考NGINX白皮书,NGINX配置HTTP2.0官方指南。</p> <p>  使用了HTTP2.0那么,原本的HTTP1.x怎么办,这个问题其实不用担心,HTTP2.0完全兼容HTTP1.x的语义,对于不支持HTTP2.0的浏览器,NGINX会自动向下兼容的。</p>
  • 屏蔽恶意蜘蛛_屏蔽垃圾蜘蛛_Nginx方式

    1.新增nginx屏蔽配置文件​文件暂时为/etc/nginx/conf.d/deny_ua.config说明:文件名deny_ua.config,后缀为.config非.conf,原因是.conf在conf.d目录下默认配置会扫描所有.c1.新增nginx屏蔽配置文件​文件暂时为/etc/nginx/conf.d/deny_ua.config说明:文件名deny_ua.config,后缀为.config非.conf,原因是.conf在conf.d目录下默认配置会扫描所有.conf文件。如果我们只希望某个站配置,则这里就不能用.conf2.deny_ua.config文件内容:  #forbidden UA if ($http_user_agent ~ "Bytespider|^$" ) {     return 403; }以上为禁用UA为空或者UA包含Bytespider的访问;如果需要屏蔽其他者修改"Bytespider|^$"  这一部分,例如屏蔽百度"BaiduSpider|Bytespider|^$" 3.在nginx对应的server片段引入配置 xxx.con.conf server{ .....其他省略.... include conf.d/deny_ua.config .....其他省略.... }  4.重启nginx nginx -s reload5.测试curl -A "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.1547.1694 Mobile Safari/537.36; Bytespider" http://www.leftso.com <html> <head><title>403 Forbidden</title></head> <body bgcolor="white"> <center><h1>403 Forbidden</h1></center> <hr><center>nginx/1.10.2</center> </body> </html>  
  • spring boot 2.0 Redis整合_spring boot 2.0 集成Redis实现缓存框架(一)

    Spring Boot 2.0 Redis整合,通过spring boot 2.0整合Redis作为spring缓存框架的实现。spring boot 2.0 Redis整合_spring boot 2.0 集成Redis实现缓存框架(一)
  • Java EE 8最受关注的新特性或者说最重要的新特性

    备受期待的Java Enterprise Edition 8发布了两个令人兴奋的新API(JSON-Binding 1.0和Java EE Security 1.0)并改进了当前的API(JAX-RS 2.1,Bean Validation 2.0,JSF 2.3,CDI 2.0,JSON-P 1.1,JPA 2.2和Servlet 4.0)。这是Oracle企业Java平台近四年来的第一个版本,它包含数百个新功能,更新的功能和错误修复。那么最好的新功能是什么?<h2>前言</h2> <blockquote> <p>    备受期待的Java Enterprise Edition 8发布了两个令人兴奋的新API(JSON-Binding 1.0和Java EE Security 1.0)并改进了当前的API(JAX-RS 2.1,Bean Validation 2.0,JSF 2.3,CDI 2.0,JSON-P 1.1,JPA 2.2和Servlet 4.0)。这是Oracle企业Java平台近四年来的第一个版本,它包含数百个新功能,更新的功能和错误修复。那么最好的新功能是什么?</p> </blockquote> <h2 style="margin-left:0px; margin-right:0px; text-align:start">前5个新功能</h2> <ul> <li><strong>新的安全API:注释驱动的身份验证机制</strong></li> </ul> 全新的安全API包含三项出色的新功能:身份库抽象,新的安全上下文以及新的注释驱动的身份验证机制,这些机制会使web.xml文件声明过时。最后一个是我今天要讨论的内容。 <ul> <li><strong>JAX-RS 2.1:新的被动式客户</strong></li> </ul> 端JAX-RS 2.1中的新型被动式客户端,采用反应式编程风格并允许组合端点结果。 <ul> <li><strong>新的JSON绑定API</strong></li> </ul> 新的JSON绑定API,为JSON序列化和反序列化提供本机Java EE解决方案。 <ul> <li><strong>CDI 2.0:在Java SE中使用CDI 2.0中</strong></li> </ul> 有趣的新功能允许在Java SE应用程序中引导CDI。 <ul> <li><strong>Servlet 4.0:服务器推送Servlet 4.0中</strong></li> </ul> 的服务器推送功能将servlet规范与HTTP / 2对齐。<br />   <h2 style="margin-left:0px; margin-right:0px; text-align:start">1.新的安全API</h2> 有可能添加到Java EE 8中的最重要的新功能是新的安全API。这个新API的主要动机是简化,标准化和现代化跨容器和实现处理安全问题的方式。 <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">Web认证<strong>的配置</strong>已经实现了现代化,这要归功于三个使web.xml文件声明成为冗余的新注释。稍后再说。</span></span></span></p> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff"><strong>新的安全上下文</strong> API标准化了servlet和EJB容器执行身份验证的方式</span></span></span></p> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff"><strong>新的Identity</strong>存储抽象简化了身份存储的使用。</span></span></span></p> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">所以我们来看看这些新增的第一个。</span></span></span></p> <h3 style="margin-left:0px; margin-right:0px; text-align:start">注释驱动的认证机制</h3> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">此功能全部是关于配置网络安全。web.xml文件中的哪个传统所需的XML声明。</span></span></span><br />  </p> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">由于<em>HttpAuthenticationMechanism</em>接口代表了HTTP身份验证,并且随附了三个内置的启用CDI的实现,这些实现代表了网络安全可以配置的三种方式之一,这已不再是必需的。</span></span></span></p> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">他们触发使用这些注释之一。</span></span></span></p> <pre> <code class="language-java">@BasicAuthenticationMechanismDefinition @FormAuthenticationMechanismDefinition @CustomFormAuthenticationMechanismDefinition</code></pre> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">它们替换了servlet容器中已有的传统HTTP基本认证,基于表单和自定义表单的认证功能已经在servlet容器中了。</span></span></span></p> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">例如,要启用基本身份验证,所需做的一切就是将@<em>BasicAuthenticationMechanismDefinition</em>注释添加到您的servlet,就像下面这样。</span></span></span></p> <pre> <code class="language-java">@BasicAuthenticationMechanismDefinition(realmName="${'user-realm'}") @WebServlet("/user") @DeclareRoles({ "admin", "user", "demo" }) @ServletSecurity(@HttpConstraint(rolesAllowed = "user")) public class UserServlet extends HttpServlet { //其他代码 }</code></pre> <p style="text-align:start">现在,您可以舍弃XML配置,并使用其中一个新注释来启用网络安全。<br /> <br />  </p> <h2 style="margin-left:0px; margin-right:0px; text-align:start">2. JAX-RS 2.1:新的反应客户端</h2> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">我们来看看JAX-RS 2.1中新的被动客户端以及它如何采用反应式编程风格。</span></span></span></p> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">被动方法的核心是<strong>数据流</strong>的概念,其中执行模型通过流传播更改。一个典型的例子是JAX-RS方法调用。当调用返回时,将对方法调用的结果执行下一个操作(可能是继续,完成或错误)。</span></span></span></p> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">您可以将其视为<strong>异步流程</strong>的流程,下一个流程将根据前一个流程的结果进行操作,然后将流程结果传递给链中的下一个流程。数据流是<strong>可组合的,</strong>因此您可以将许多流合并并转换为一个结果。</span></span></span></p> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">通过<em>调用</em>用于构造客户端实例的<em>Invocation.Builder</em>实例上的<em>rx()</em>方法来启用反应性功能。它的返回类型是<strong>具有参数化</strong><strong><em>响应</em></strong><strong>类型</strong>的<strong><em>CompletionStage</em></strong>。该<em>CompletionStage</em>接口是用Java 8中引入,并提出了一些有趣的可能性。</span></span></span></p> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">例如,在这个代码片段中,两个调用是对不同的端点进行的,然后将结果合并:</span></span></span></p> <pre> <code class="language-java">CompletionStage<Response> cs1 = ClientBuilder.newClient() .target(".../books/history") .request() .rx() .get(); CompletionStage<Response> cs2 = ClientBuilder.newClient() .target(".../books/geology") .request() .rx() .get(); cs1.thenCombine(cs2, (r1, r2) -> r1.readEntity(String.class) + r2.readEntity(String.class)) .thenAccept(System.out::println);</code></pre> <h2 style="margin-left:0px; margin-right:0px; text-align:start">3.新的JSON绑定API</h2> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">现在我们来看看下一个伟大的功能。新的JSON绑定API,此API为<strong>JSON序列化和反序列化</strong>提供<strong>了原生Java EE解决方案</strong>。</span></span></span></p> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">以前,如果您想要将JSON序列化和反序列化,则必须依赖Jackson或GSON等第三方API。不再。使用新的JSON绑定API,您可以使用本地可用的所有功能。</span></span></span></p> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">从Java对象生成JSON文档并不那么简单。只需调用<em>toJson()</em>方法并将它传递给想要序列化的实例即可。</span></span></span></p> <pre> <code class="language-java">String bookJson = JsonbBuilder.create().toJson(book); </code></pre> <h3 style="margin-left:0px; margin-right:0px; text-align:start">行为定制</h3> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">可以通过注释字段,JavaBean方法和类来自定义默认的序列化和反序列化行为。</span></span></span></p> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">例如,您可以使用<em>@JsonbNillable</em>来自定义空处理和<em>@JsonbPropertyOrder</em>注释来自定义您在类级别指定的属性顺序。你可以指定与数字格式<em>@JsonbNumberFormat()</em>注解,并与更改字段的名称<em>@JsonbProperty()</em>注释。</span></span></span></p> <pre> <code class="language-java">@JsonbNillable @JsonbPropertyOrder(PropertyOrderStrategy.REVERSE) public class Booklet { @JsonbProperty("cost") @JsonbNumberFormat("#0.00") private Float price; }</code></pre> 或者,您可以选择使用运行时配置构建器<em>JsonbConfig</em>处理自定义: <pre> <code class="language-java">JsonbConfig jsonbConfig = new JsonbConfig() .withPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE_WITH_DASHES) .withNullValues(true) .withFormatting(true); Jsonb jsonb = JsonbBuilder.create(jsonbConfig);</code></pre> 无论哪种方式,JSON绑定API都为Java对象的序列化和反序列化提供了广泛的功能。 <h2 style="margin-left:0px; margin-right:0px; text-align:start">4. CDI 2.0:在Java SE中使用</h2> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">现在让我们继续看下一个API。CDI 2.0 API。该版本拥有许多新功能,其中一个更有趣的功能是<strong>在Java SE应用程序中引导CDI</strong>的功能。</span></span></span></p> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">要在Java SE中使用CDI,必须明确引导CDI容器。这是通过调用<strong><em>SeContainerInitializer</em></strong><strong>抽象类</strong>的<strong>静态方法  </strong><strong><em>newInstance()</em></strong><strong>来实现的</strong>。它返回一个<em>SeContainer</em>实例,该实例是CDI运行时的句柄,您可以使用该句柄执行CDI解析,如此代码片段中所示。它可以访问作为CDI核心入口点的BeanManager。</span></span></span><br />  </p> <pre> <code class="language-java">SeContainer seContainer = SeContainerInitializer.newInstance().initialize(); Greeting greeting = seContainer.select(Greeting.class).get(); greeting.printMessage("Hello World"); seContainer.close();</code></pre> 使用<em>select()</em>方法检索CDI bean,方法是传递要检索和使用的bean的类名称。 <h3 style="margin-left:0px; margin-right:0px; text-align:start">配置选项</h3> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">可以通过添加拦截器,扩展,替代方法,属性和装饰器来<strong>进一步配置</strong><em>SeContext</em>。</span></span></span></p> <pre> <code class="language-java">.enableInterceptors() .addExtensions() .selectAlternatives() .setProperties() .enableDecorators()</code></pre> 通过在<em>SeContainer</em>上调用<em>close()</em>方法手动关闭容器,或者在使用<em>Try  </em><em>-with-resources</em>结构时自动关闭容器,因为<em>SeContainer</em>  扩展了<em>AutoCloseable</em>  接口。 <h2 style="margin-left:0px; margin-right:0px; text-align:start">5. Servlet 4.0:服务器推送</h2> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">最后但并非最不重要的一点是,Servlet 4.0中的服务器推送功能使servlet规范与HTTP / 2保持一致。</span></span></span></p> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">要理解此功能,您首先需要知道服务器推送的内容。</span></span></span></p> <h3 style="margin-left:0px; margin-right:0px; text-align:start">什么是服务器推送?</h3> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">服务器推送是HTTP / 2协议中的许多新功能之一,旨在通过将这些资源推送到浏览器的缓存中来预测客户端资源需求,以便当客户端发送网页请求并接收到响应时从服务器,它需要的资源已经在缓存中。这是一项提高网页加载速度的性能增强功能。</span></span></span></p> <h3 style="margin-left:0px; margin-right:0px; text-align:start">它如何在Servlet 4.0中公开?</h3> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">在Servlet 4.0中,<strong>Server Push功能通过</strong>从<em>HttpServletRequest</em>实例获得<strong>的</strong><strong><em>PushBuilder</em></strong><strong>实例</strong><strong>公开</strong>。</span></span></span></p> <p style="text-align:start"><span style="color:#333333"><span style="font-family:Tahoma,Arial,Verdana,sans-serif"><span style="background-color:#ffffff">看看这段代码片段。您可以看到,通过<em>path()</em>方法在<em>PushBuilder</em>实例上设置了<em>header.png</em>的<em>路径</em>,并通过调用<em>push()</em>将其推送到客户端。当方法返回时,路径和条件头部将被清除,以便构建器重用。该<em>menu.css</em>文件推,然后<em>ajax.js</em> javascript文件推送到客户端。</span></span></span></p> <pre> <code class="language-java">protected void doGet(HttpServletRequest request, HttpServletResponse response) { PushBuilder pushBuilder = request.newPushBuilder(); pushBuilder.path("images/header.png").push(); pushBuilder.path("css/menu.css").push(); pushBuilder.path("js/ajax.js").push(); // Return JSP that requires these resources }</code></pre> 在Servlet <em>doGet()</em>方法完成执行时,资源将到达浏览器。从JSP生成的需要这些资源的HTML不需要从服务器请求它们,因为它们已经是浏览器缓存。<br />  
  • Python教程-Python httplib2 HTTP GET和POST使用详解

    Python httplib2 简介学习使用Python httplib2模块Python httplib2 简介学习使用Python httplib2模块。的超文本传输协议(HTTP)是用于分布式,协作,超媒体信息系统的应用协议。HTTP是万维网数据通信的基础。Python httplib2模块提供了用于通过HTTP访问Web资源的方法。它支持许多功能,例如HTTP和HTTPS,身份验证,缓存,重定向和压缩。检查httplib2库版本第一个程序打印库的版本,其版权和文档字符串。import httplib2 print(httplib2.__version__) print(httplib2.__copyright__) print(httplib2.__doc__)在httplib2.__version__给出的版本httplib2库中,httplib2.__copyright__给出了其版权,以及httplib2.__doc__它的文档字符串。执行上方的代码可能遇到模块未找到错误,如下图:​如果出现上方问题,我们进行安装该模块即可,以下为Python 3.x版本的安装命令pip3 install httplib2 --upgrade 安装过程如下:​httplib2 安装 安装完成后我们再次执行版本检查的代码:​httplib2信息查看  使用httplib2读取网页 在下面的示例中,我们展示了如何从名为http://www.baidu.com的网站获取HTML内容。import httplib2 http = httplib2.Http() content = http.request("http://www.baidu.com")[1] print(content.decode()) 使用创建一个HTTP客户端httplib2.HTTP()。使用该request()方法创建一个新的HTTP请求。默认情况下,它是一个GET请求。返回值是响应和内容的元组。响应部分内容展示:​剥离HTML标签 以下程序获取一个小型网页,并剥离其HTML标签。import httplib2 import re http = httplib2.Http() content = http.request("http://www.baidu.com")[1] stripped = re.sub('<[^<]+?>', '', content.decode()) print(stripped) 一个简单的正则表达式用于剥离HTML标记。请注意,我们正在剥离数据,我们没有对其进行清理。(这是两总不同的情况。)​检查响应状态 响应对象包含一个status给出响应状态代码的属性。import httplib2 http = httplib2.Http() resp = http.request("http://www.baidu.com")[0] print(resp.status) resp = http.request("http://www.leftso.com/blog/0.html")[0] print(resp.status) 我们使用request()方法执行两个HTTP请求,并检查返回的状态。​200是成功HTTP请求的标准响应,而404则表明找不到所请求的资源。发送HTTP HEAD请求 HTTP HEAD方法检索文档标题。标头由字段组成,包括日期,服务器,内容类型或上次修改时间。import httplib2 http = httplib2.Http() resp = http.request("http://www.leftso.com/assist/images/carousel/855892C7F4734F3CB0721835573BAD07.jpg", "HEAD")[0] print("Server: " + resp['server']) print("Last modified: " + resp['last-modified']) print("Content type: " + resp['content-type']) print("Content length: " + resp['content-length']) ​这是程序的输出。从输出中,我们可以看到该网页是由FreeBSD托管的Apache Web服务器交付的。该文档的最后修改时间是1999年。网页是HTML文档,其长度为72个字节。发送HTTP GET请求 HTTP GET方法请求指定资源的表示形式。对于此示例,我们还将使用greet.php脚本:<?php echo "Hello " . htmlspecialchars($_GET['name']); ?> 在/usr/share/nginx/html/目录中,我们有此greet.php文件。该脚本返回name变量的值,该值是从客户端检索到的。该htmlspecialchars()函数将特殊字符转换为HTML实体;例如&到&amp.。import httplib2 http = httplib2.Http() content = http.request("http://localhost/greet.php?name=Peter", method="GET")[1] print(content.decode()) 该脚本将带有值的变量发送到服务器上的PHP脚本。该变量直接在URL中指定。Hello Peter 这是示例的输出。127.0.0.1 - - [21/Aug/2016:17:32:31 +0200] "GET /greet.php?name=Peter HTTP/1.1" 200 42 "-" "Python-httplib2/0.8 (gzip)" 我们检查了nginx访问日志。发送HTTP POST请求 POST请求方法请求Web服务器接受并存储请求消息正文中包含的数据。上载文件或提交完整的Web表单时经常使用它。<?php echo "Hello " . htmlspecialchars($_POST['name']); ?> 在本地Web服务器上,我们有此target.php文件。它只是将过帐的值打印回客户。import httplib2 import urllib http = httplib2.Http() body = {'name': 'Peter'} content = http.request("http://localhost/target.php", method="POST", headers={'Content-type': 'application/x-www-form-urlencoded'}, body=urllib.parse.urlencode(body) )[1] print(content.decode()) 脚本发送name带有Peter值的键的请求。数据使用urllib.parse.urlencode()方法进行编码,并在请求的正文中发送。Hello Peter 这是mpost.py脚本的输出。 127.0.0.1 - - [23/Aug/2016:12:21:07 +0200] "POST /target.php HTTP/1.1" 200 37 "-" "Python-httplib2/0.8 (gzip)" 使用POST方法时,不会在请求URL中发送该值。发送用户代理信息 在本节中,我们指定用户代理的名称。<?php echo $_SERVER['HTTP_USER_AGENT']; ?> 在nginx文档根目录下,我们有agent.php文件。它返回用户代理的名称。import httplib2 http = httplib2.Http() content = http.request("http://localhost/agent.php", method="GET", headers={'user-agent': 'Python script'})[1] print(content.decode()) 该脚本向脚本创建一个简单的GET请求agent.php。在headers字典中,我们指定用户代理。这可以通过PHP脚本读取,并返回给客户端。Python script 服务器使用我们随请求发送的代理名称进行了响应。将用户名/密码添加到请求 客户端的add_credentials()方法设置用于领域的名称和密码。安全领域是一种用于保护Web应用程序资源的机制。$ sudo apt-get install apache2-utils $ sudo htpasswd -c /etc/nginx/.htpasswd user7 New password: Re-type new password: Adding password for user user7 我们使用该htpasswd工具创建用于基本HTTP身份验证的用户名和密码。location /secure { auth_basic "Restricted Area"; auth_basic_user_file /etc/nginx/.htpasswd; } 在nginx /etc/nginx/sites-available/default配置文件中,我们创建一个安全页面。领域的名称是“禁区”。<!DOCTYPE html> <html lang="en"> <head> <title>Secure page</title> </head> <body> <p> This is a secure page. </p> </body> </html> 在/usr/share/nginx/html/secure目录中,我们有上面的HTML文件。import httplib2 user = 'user7' passwd = '7user' http = httplib2.Http() http.add_credentials(user, passwd) content = http.request("http://localhost/secure/")[1] print(content.decode()) 该脚本连接到安全网页;它提供访问该页面所需的用户名和密码。<!DOCTYPE html> <html lang="en"> <head> <title>Secure page</title> </head> <body> <p> This is a secure page. </p> </body> </html> 使用正确的凭据,脚本将返回受保护的页面。在本教程中,我们探索了Python httplib2模块。
  • Spring Boot 2.0 Websocket Angular整合

    Spring Boot 2.0 Websocket Angular整合Spring Boot 2.0 Websocket Angular整合
  • Newifi3 D2 硬件参数

    ​Newifi3 D2 硬件参数信息 Newifi3 D2 硬件配置信息 SOCMT7621A2.4G无线芯片MT7603EN5G 无线芯片MT7612EN5G 功放芯片SKY85717-21RAM内存512MBROM闪存32MB2.4G​Newifi3 D2 硬件参数信息 Newifi3 D2 硬件配置信息 SOCMT7621A2.4G无线芯片MT7603EN5G 无线芯片MT7612EN5G 功放芯片SKY85717-21RAM内存512MBROM闪存32MB2.4G 最大速率300Mbps5G最大速率867MbpsWLAN口速率1GbpsLAN口速率1GbpsLAN口数量4天线类型外置不可拆卸4根天线增益2.4G天线增益5dBi/5G天线增益6dBiUSB 3.01是否支持刷机是(可以刷padavan/op等)当前参考价格90关联文章:Newifi 3 D2刷BREED教程小米路由器3G 对比 Newifi3 D2(新路由3)
  • Spring Security OAuth 2开发者指南

    本文主要翻译spring官方的基于spring security框架的oauth2开发指南,spring,oauth2,spring框架,Java编程<h2>介绍</h2> <p>这是用户指南的支持<a href="https://tools.ietf.org/html/draft-ietf-oauth-v2" rel="external nofollow" target="_blank"><code>OAuth 2.0</code></a>。对于OAuth 1.0,一切都是不同的,所以<a href="http://projects.spring.io/spring-security-oauth/docs/oauth1.html" rel="external nofollow" target="_blank">看到它的用户指南</a>。</p> <p>本用户指南分为两部分,第一部分为OAuth 2.0提供者,第二部分为OAuth 2.0客户端。对于提供商和客户端,示例代码的最佳来源是<a href="https://github.com/spring-projects/spring-security-oauth/tree/master/tests" rel="external nofollow" target="_blank">集成测试</a>和<a href="https://github.com/spring-projects/spring-security-oauth/tree/master/samples/oauth2" rel="external nofollow" target="_blank">示例应用程序</a>。</p> <h2>OAuth 2.0提供程序</h2> <p>OAuth 2.0提供者机制负责公开OAuth 2.0受保护的资源。该配置包括建立可独立或代表用户访问其受保护资源的OAuth 2.0客户端。提供者通过管理和验证用于访问受保护资源的OAuth 2.0令牌来实现。在适用的情况下,提供商还必须提供用户界面,以确认客户端可以被授权访问受保护资源(即确认页面)。</p> <h2>OAuth 2.0提供程序实现</h2> <p>OAuth 2.0中的提供者角色实际上是在授权服务和资源服务之间分割的,而有时它们位于同一个应用程序中,使用Spring Security OAuth,您可以选择在两个应用程序之间进行拆分,并且还可以共享多个资源服务授权服务。令牌的请求由Spring MVC控制器端点处理,对受保护资源的访问由标准的Spring Security请求过滤器处理。为了实现OAuth 2.0授权服务器,Spring Security过滤器链中需要以下端点:</p> <ul> <li><a href="http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.html" rel="external nofollow" target="_blank" title="授权终点"><code>AuthorizationEndpoint</code></a>用于服务授权请求。默认网址:<code>/oauth/authorize</code>。</li> <li><a href="http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.html" rel="external nofollow" target="_blank" title="令牌终点"><code>TokenEndpoint</code></a>用于服务访问令牌的请求。默认网址:<code>/oauth/token</code>。</li> </ul> <p>实施OAuth 2.0资源服务器需要以下过滤器:</p> <ul> <li>将<a href="http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilter.html" rel="external nofollow" target="_blank" title="OAuth2AuthenticationProcessingFilter"><code>OAuth2AuthenticationProcessingFilter</code></a>用于加载给定的认证访问令牌请求的认证。</li> </ul> <p>对于所有OAuth 2.0提供程序功能,使用特殊的Spring OAuth <code>@Configuration</code>适配器简化了配置。还有一个用于OAuth配置的XML命名空间,并且模式位于<a href="http://www.springframework.org/schema/security/spring-security-oauth2.xsd" rel="external nofollow" target="_blank" title="oauth2.xsd">http://www.springframework.org/schema/security/spring-security-oauth2.xsd</a>。命名空间是<code>http://www.springframework.org/schema/security/oauth2</code>。</p> <h2>授权服务器配置</h2> <p>在配置授权服务器时,必须考虑客户端用于从最终用户获取访问令牌(例如授权代码,用户凭据,刷新令牌)的授权类型。服务器的配置用于提供客户端详细信息服务和令牌服务的实现,并且启用或禁用全局机制的某些方面。但是请注意,每个客户端都可以特别配置,以便能够使用某些授权机制和访问授权。也就是因为您的提供商配置为支持“客户端凭据”授权类型,并不意味着特定客户端被授权使用该授权类型。</p> <p>该<code>@EnableAuthorizationServer</code>注释用于配置OAuth 2.0授权服务器机制,以及任何<code>@Beans</code>实现<code>AuthorizationServerConfigurer</code>(有一个方便的适配器实现)。将以下功能委派给由Spring创建并传递到以下内容的单独配置程序<code>AuthorizationServerConfigurer</code>:</p> <ul> <li><code>ClientDetailsServiceConfigurer</code>:一个定义客户端详细信息服务的配置程序。客户端的详细信息可以初始化,也可以参考现有的存储。</li> <li><code>AuthorizationServerSecurityConfigurer</code>:定义令牌端点上的安全约束。</li> <li><code>AuthorizationServerEndpointsConfigurer</code>:定义授权和令牌端点和令牌服务。</li> </ul> <p>提供商配置的一个重要方面是授权代码提供给OAuth客户端(授权代码授权)的方式。授权代码由OAuth客户端通过将最终用户指向用户可以输入其凭据的授权页面获得,导致从提供商授权服务器重定向到具有授权码的OAuth客户端。这在OAuth 2规范中有详细说明。</p> <p>在XML中,有一个<code><authorization-server/></code>元素以类似的方式用于配置OAuth 2.0授权服务器。</p> <h3>配置客户端详细信息</h3> <p>将<code>ClientDetailsServiceConfigurer</code>(从您的回调<code>AuthorizationServerConfigurer</code>)可以用来在内存或JDBC实现客户的细节服务来定义的。客户端的重要属性是</p> <ul> <li><code>clientId</code>:(必填)客户端ID。</li> <li><code>secret</code>:(可信客户端需要)客户机密码(如果有)。</li> <li><code>scope</code>:客户受限的范围。如果范围未定义或为空(默认值),客户端不受范围限制。</li> <li><code>authorizedGrantTypes</code>:授予客户端使用授权的类型。默认值为空。</li> <li><code>authorities</code>授予客户的授权机构(普通的Spring Security权威机构)。</li> </ul> <p>客户端的详细信息可以通过直接访问底层商店(例如,在数据库表中<code>JdbcClientDetailsService</code>)或通过<code>ClientDetailsManager</code>接口(这两种实现<code>ClientDetailsService</code>也实现)来更新运行的应用程序。</p> <p>注意:JDBC服务的架构未与库一起打包(因为在实践中可能需要使用太多变体),而是可以从<a href="https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/test/resources/schema.sql" rel="external nofollow" target="_blank">github</a>中的<a href="https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/test/resources/schema.sql" rel="external nofollow" target="_blank">测试代码中</a>开始。</p> <h3>管理令牌</h3> <p>该<a href="http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/token/AuthorizationServerTokenServices.html" rel="external nofollow" target="_blank" title="AuthorizationServerTokenServices"><code>AuthorizationServerTokenServices</code></a>接口定义了所必需的管理OAuth 2.0令牌的操作。请注意以下事项:</p> <ul> <li>当创建访问令牌时,必须存储身份验证,以便接受访问令牌的资源可以稍后引用。</li> <li>访问令牌用于加载用于授权其创建的认证。</li> </ul> <p>在创建<code>AuthorizationServerTokenServices</code>实现时,您可能需要考虑使用<a href="http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/token/DefaultTokenServices.html" rel="external nofollow" target="_blank" title="DefaultTokenServices"><code>DefaultTokenServices</code></a>可插入的策略来更改访问令牌的格式和存储。默认情况下,它将通过随机值创建令牌,并处理除代表它的令牌持久化之外的所有内容<code>TokenStore</code>。默认存储是<a href="http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/token/store/InMemoryTokenStore.html" rel="external nofollow" target="_blank" title="InMemoryTokenStore">内存中的实现</a>,但还有一些其他可用的实现。这是一个关于每一个的一些讨论的描述</p> <ul> <li> <p>默认值<code>InMemoryTokenStore</code>对于单个服务器是完全正常的(即,在发生故障的情况下,低流量和热备份备份服务器)。大多数项目可以从这里开始,也可以在开发模式下运行,以便轻松启动没有依赖关系的服务器。</p> </li> <li> <p>这<code>JdbcTokenStore</code>是同一件事的<a href="http://projects.spring.io/spring-security-oauth/docs/JdbcTokenStore" rel="external nofollow" target="_blank">JDBC版本</a>,它将令牌数据存储在关系数据库中。如果您可以在服务器之间共享数据库,则可以使用JDBC版本,如果只有一个,则扩展同一服务器的实例,或者如果有多个组件,则授权和资源服务器。要使用<code>JdbcTokenStore</code>你需要“spring-jdbc”的类路径。</p> </li> <li> <p>商店的<a href="http://projects.spring.io/spring-security-oauth/docs/%60JwtTokenStore%60" rel="external nofollow" target="_blank">JSON Web令牌(JWT)版本</a>将所有关于授权的数据编码到令牌本身(因此,根本没有后端存储是一个显着的优势)。一个缺点是您不能轻易地撤销访问令牌,因此通常被授予短期到期权,撤销在刷新令牌处理。另一个缺点是,如果您在其中存储了大量用户凭据信息,令牌可能会变得非常大。这<code>JwtTokenStore</code>不是一个真正的“商店”,因为它不会保留任何数据,但它在翻译令牌值和验证信息之间起着相同的作用<code>DefaultTokenServices</code>。</p> </li> </ul> <p>注意:JDBC服务的架构未与库一起打包(因为在实践中可能需要使用太多变体),而是可以从<a href="https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/test/resources/schema.sql" rel="external nofollow" target="_blank">github</a>中的<a href="https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/test/resources/schema.sql" rel="external nofollow" target="_blank">测试代码中</a>开始。确保<code>@EnableTransactionManagement</code>在创建令牌时,防止在竞争相同行的客户端应用程序之间发生冲突。还要注意,示例模式有明确的<code>PRIMARY KEY</code>声明 - 这些在并发环境中也是必需的。</p> <h3>JWT令牌</h3> <p>要使用JWT令牌,您需要<code>JwtTokenStore</code>在授权服务器中。资源服务器还需要能够对令牌进行解码,因此它<code>JwtTokenStore</code>具有依赖性<code>JwtAccessTokenConverter</code>,并且授权服务器和资源服务器都需要相同的实现。默认情况下,令牌被签名,资源服务器还必须能够验证签名,因此它需要与授权服务器(共享密钥或对称密钥)相同的对称(签名)密钥,或者需要公共密钥(验证者密钥),其与授权服务器中的私钥(签名密钥)匹配(公私属或非对称密钥)。公钥(如果可用)由<code>/oauth/token_key</code>端点上的授权服务器公开,默认情况下,访问规则为“denyAll()”。<code>AuthorizationServerSecurityConfigurer</code></p> <p>要使用<code>JwtTokenStore</code>你需要的“spring-security-jwt”你的类路径(你可以在与Spring OAuth相同的github仓库中找到它,但发行周期不同)。</p> <h3>赠款类型</h3> <p><code>AuthorizationEndpoint</code>可以通过以下方式配置支持的授权类型<code>AuthorizationServerEndpointsConfigurer</code>。默认情况下,所有授权类型均受支持,除了密码(有关如何切换它的详细信息,请参见下文)。以下属性会影响授权类型:</p> <ul> <li><code>authenticationManager</code>:通过注入密码授权被打开<code>AuthenticationManager</code>。</li> <li><code>userDetailsService</code>:如果您注入<code>UserDetailsService</code>或者全局配置(例如a <code>GlobalAuthenticationManagerConfigurer</code>),则刷新令牌授权将包含对用户详细信息的检查,以确保该帐户仍然活动</li> <li><code>authorizationCodeServices</code>:定义<code>AuthorizationCodeServices</code>授权代码授权的授权代码服务(实例)。</li> <li><code>implicitGrantService</code>:在批准期间管理状态。</li> <li><code>tokenGranter</code>:(<code>TokenGranter</code>完全控制授予和忽略上述其他属性)</li> </ul> <p>在XML授予类型中包含作为子元素<code>authorization-server</code>。</p> <h3>配置端点URL</h3> <p>该<code>AuthorizationServerEndpointsConfigurer</code>有一个<code>pathMapping()</code>方法。它有两个参数:</p> <ul> <li>端点的默认(框架实现)URL路径</li> <li>需要的自定义路径(以“/”开头)</li> </ul> <p>由框架提供的URL路径<code>/oauth/authorize</code>(授权端点)<code>/oauth/token</code>(令牌端点)<code>/oauth/confirm_access</code>(用户发布批准此处)<code>/oauth/error</code>(用于在授权服务器中呈现错误)<code>/oauth/check_token</code>(由资源服务器用于解码访问令牌) ,并且<code>/oauth/token_key</code>(如果使用JWT令牌,则公开用于令牌验证的公钥)。</p> <p>注意,授权端点<code>/oauth/authorize</code>(或其映射替代方案)应使用Spring Security进行保护,以便只有经过身份验证的用户才能访问。例如使用标准的Spring Security <code>WebSecurityConfigurer</code>:</p> <pre> <code class="language-java"> @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests().antMatchers("/login").permitAll().and() // default protection for all resources (including /oauth/authorize) .authorizeRequests() .anyRequest().hasRole("USER") // ... more configuration, e.g. for form login } </code></pre> <p>注意:如果您的授权服务器也是资源服务器,那么还有另一个优先级较低的安全过滤器链控制API资源。通过访问令牌来保护这些请求,您需要他们的路径<em>不</em>与主用户面临的过滤器链中的路径匹配,因此请务必包含仅在<code>WebSecurityConfigurer</code>上述中选择非API资源的请求匹配器。</p> <p>默认情况下,通过Spring OAuth在<code>@Configuration</code>使用客户机密码的HTTP Basic认证的支持中为您保护令牌端点。在XML中不是这样(因此应该明确保护)。</p> <p>在XML中,<code><authorization-server/></code>元素具有一些可以用于以类似方式更改默认端点URL的属性。该<code>/check_token</code>端点必须(与显式启用<code>check-token-enabled</code>属性)。</p> <h2>自定义UI</h2> <p>大多数授权服务器端点主要由机器使用,但是有一些资源需要一个UI,而这些资源是GET <code>/oauth/confirm_access</code>和HTML响应<code>/oauth/error</code>。它们是在框架中使用白名单实现提供的,因此授权服务器的大多数真实世界实例都希望提供自己的实例,以便他们可以控制样式和内容。所有您需要做的是<code>@RequestMappings</code>为这些端点提供一个Spring MVC控制器,并且框架默认在调度程序中占用较低的优先级。在<code>/oauth/confirm_access</code>端点中,您可以期待<code>AuthorizationRequest</code>绑定到会话中,携带所有需要用户查询的数据(默认的实现是<code>WhitelabelApprovalEndpoint</code>这样查找起始点复制)。<code>/oauth/authorize</code>您可以从该请求中获取所有数据,然后根据需要进行渲染,然后所有用户需要执行的操作都是回复有关批准或拒绝授权的信息。请求参数直接传递给您<code>UserApprovalHandler</code>,<code>AuthorizationEndpoint</code>所以您可以随便解释数据。默认<code>UserApprovalHandler</code>取决于您是否已经提供了一个<code>ApprovalStore</code>在你的<code>AuthorizationServerEndpointsConfigurer</code>(在这种情况下,它是一个<code>ApprovalStoreUserApprovalHandler</code>)或不(在这种情况下,它是一个<code>TokenStoreUserApprovalHandler</code>)。标准审批处理程序接受以下内容:默认取决于您是否已经提供了一个在你的(在这种情况下,它是一个)或不(在这种情况下,它是一个)。标准审批处理程序接受以下内容:默认取决于您是否已经提供了一个在你的(在这种情况下,它是一个)或不(在这种情况下,它是一个)。标准审批处理程序接受以下内容:</p> <ul> <li> <p><code>TokenStoreUserApprovalHandler</code>:简单的是/否决定通过<code>user_oauth_approval</code>等于“真”或“假”。</p> </li> <li> <p><code>ApprovalStoreUserApprovalHandler</code>:一组<code>scope.*</code>参数键与“*”等于所请求的范围。参数的值可以是“true”或“approved”(如果用户批准了授权),则该用户被认为已经拒绝了该范围。如果批准了至少一个范围,则赠款是成功的。</p> </li> </ul> <p>注意:不要忘记在您为用户呈现的表单中包含CSRF保护。默认情况下,Spring Security正期待一个名为“_csrf”的请求参数(它在请求属性中提供值)。有关更多信息,请参阅Spring Security用户指南,或查看whitelabel实现的指导。</p> <h3>执行SSL</h3> <p>普通HTTP对于测试是很好的,但授权服务器只能在生产中使用SSL。您可以在安全容器或代理服务器后面运行应用程序,如果正确设置代理和容器(这与OAuth2无关),则应该可以正常运行。您也可能希望使用Spring Security <code>requiresChannel()</code>限制来保护端点。对于<code>/authorize</code>端点,由您来做,作为您正常应用程序安全性的一部分。对于<code>/token</code>端点<code>AuthorizationServerEndpointsConfigurer</code>,可以使用该<code>sslOnly()</code>方法设置一个标志。在这两种情况下,安全通道设置是可选的,但是如果Spring Security在不安全的通道上检测到请求,则会导致Spring Security重定向到安全通道。</p> <h2>自定义错误处理</h2> <p>授权服务器中的错误处理使用标准Spring MVC功能,即<code>@ExceptionHandler</code>端点本身的方法。用户还可以向<code>WebResponseExceptionTranslator</code>端点自身提供这些改变响应内容的最佳方式,而不是渲染方式。在授权<code>HttpMesssageConverters</code>端点的情况下,在令牌端点和OAuth错误视图(<code>/oauth/error</code>)的情况下,异常呈现(可以添加到MVC配置中)。该白色标签错误的端点提供了HTML的响应,但用户可能需要提供自定义实现(如只需添加一个<code>@Controller</code>带<code>@RequestMapping("/oauth/error")</code>)。</p> <h2>将用户角色映射到范围</h2> <p>限制令牌范围不仅仅是分配给客户端的范围,还可以根据用户自己的权限来进行限制。如果您在其中使用<code>DefaultOAuth2RequestFactory</code>,<code>AuthorizationEndpoint</code>则可以设置一个标志<code>checkUserScopes=true</code>,以将允许的范围限制为仅与那些与用户角色匹配的范围。你也可以注入<code>OAuth2RequestFactory</code>,<code>TokenEndpoint</code>但只有工作(即密码授权),如果你也安装一个<code>TokenEndpointAuthenticationFilter</code>- 你只需要在HTTP之后添加该过滤器<code>BasicAuthenticationFilter</code>。当然,您还可以实现自己的规则,将作用域映射到角色并安装自己的版本<code>OAuth2RequestFactory</code>。将<code>AuthorizationServerEndpointsConfigurer</code>让你注入一个定制的<code>OAuth2RequestFactory</code>,所以你可以使用该功能来建立一个工厂,如果你使用<code>@EnableAuthorizationServer</code>。</p> <h2>资源服务器配置</h2> <p>资源服务器(可以与授权服务器或单独的应用程序相同)提供受OAuth2令牌保护的资源。Spring OAuth提供了实现此保护的Spring Security认证过滤器。您可以<code>@EnableResourceServer</code>在<code>@Configuration</code>类上打开它,并使用a进行配置(必要时)<code>ResourceServerConfigurer</code>。可以配置以下功能:</p> <ul> <li><code>tokenServices</code>:定义令牌服务的bean(实例<code>ResourceServerTokenServices</code>)。</li> <li><code>resourceId</code>:资源的ID(可选,但建议并由验证服务器验证,如果存在)。</li> <li>其他扩展点(例如<code>tokenExtractor</code>从传入请求中提取令牌)</li> <li>请求匹配的受保护资源(默认为全部)</li> <li>受保护资源的访问规则(默认为“已验证”)</li> <li><code>HttpSecurity</code>Spring Security中配置程序允许的受保护资源的其他自定义</li> </ul> <p>该<code>@EnableResourceServer</code>注释添加类型的过滤器<code>OAuth2AuthenticationProcessingFilter</code>自动Spring Security的过滤器链。</p> <p>在XML中有一个<code><resource-server/></code>带有<code>id</code>属性的元素- 这是一个servlet的bean ID,<code>Filter</code>然后可以手动添加到标准的Spring Security链。</p> <p>您<code>ResourceServerTokenServices</code>是与授权服务器的合同的另一半。如果资源服务器和授权服务器在同一个应用程序中,然后使用,<code>DefaultTokenServices</code>那么您不需要太费心思考,因为它实现了所有必要的接口,因此它自动一致。如果您的资源服务器是一个单独的应用程序,那么您必须确保与授权服务器的功能相匹配,并提供一个<code>ResourceServerTokenServices</code>正确的解码令牌。与授权服务器一样,您经常可以使用该<code>DefaultTokenServices</code>选项,并且选择主要通过<code>TokenStore</code>(后端存储或本地编码)来表达。<code>RemoteTokenServices</code>一个替代方案是Spring OAuth功能(不是规范的一部分),允许资源服务器通过授权服务器(<code>/oauth/check_token</code>)上的HTTP资源解码令牌。<code>RemoteTokenServices</code>如果资源服务器中没有大量的流量(每个请求都必须与授权服务器进行验证),或者如果能够缓存结果,那么它们是方便的。要使用<code>/oauth/check_token</code>端点,您需要通过更改其访问规则(默认为“denyAll()”)来公开它<code>AuthorizationServerSecurityConfigurer</code>,例如</p> <pre> <code class="language-java"> @Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { oauthServer.tokenKeyAccess("isAnonymous() || hasAuthority('ROLE_TRUSTED_CLIENT')").checkTokenAccess( "hasAuthority('ROLE_TRUSTED_CLIENT')"); } </code></pre> <p>在这个例子中,我们配置了<code>/oauth/check_token</code>端点和<code>/oauth/token_key</code>端点(所以信任的资源可以获得JWT验证的公钥)。这两个端点受到使用客户端凭据的HTTP基本身份验证的保护。</p> <h3>配置OAuth感知表达式处理程序</h3> <p>您可能希望利用Spring Security <a href="http://docs.spring.io/spring-security/site/docs/3.2.5.RELEASE/reference/htmlsingle/#el-access" rel="external nofollow" target="_blank" title="表达式访问控制">基于表达式的访问控制</a>。表达式处理程序将默认在<code>@EnableResourceServer</code>安装程序中注册。这些表达式包括<em>#oauth2.clientHasRole</em>,<em>#oauth2.clientHasAnyRole</em>和<em>#oath2.denyClient</em>,可用于根据oauth客户端的角色提供访问(请参阅<code>OAuth2SecurityExpressionMethods</code>全面的列表)。在XML中,您可以<code>expression-handler</code>使用常规<code><http/></code>安全配置的元素注册一个oauth感知表达式处理程序。</p> <h2>OAuth 2.0客户端</h2> <p>OAuth 2.0客户端机制负责访问其他服务器的OAuth 2.0保护资源。该配置包括建立用户可能访问的相关受保护资源。客户端还可能需要提供用于存储用户的授权码和访问令牌的机制。</p> <h3>受保护的资源配置</h3> <p>受保护的资源(或“远程资源”)可以使用类型的bean定义来定义<a href="http://projects.spring.io/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/resource/OAuth2ProtectedResourceDetails.java" rel="external nofollow" target="_blank"><code>OAuth2ProtectedResourceDetails</code></a>。受保护的资源具有以下属性:</p> <ul> <li><code>id</code>:资源的id。该id仅由客户端用于查找资源; 它在OAuth协议中从未使用过。它也被用作bean的id。</li> <li><code>clientId</code>:OAuth客户端ID。这是OAuth提供商识别您的客户端的ID。</li> <li><code>clientSecret</code>:与资源相关的秘密。默认情况下,没有密码为空。</li> <li><code>accessTokenUri</code>:提供访问令牌的提供者OAuth端点的URI。</li> <li><code>scope</code>:逗号分隔的字符串列表,指定对资源的访问范围。默认情况下,不指定范围。</li> <li><code>clientAuthenticationScheme</code>:您的客户端用于向访问令牌端点进行身份验证的方案。建议的值:“http_basic”和“form”。默认值为“http_basic”。请参阅OAuth 2规范的第2.1节。</li> </ul> <p>不同的授权类型具有不同的具体实现<code>OAuth2ProtectedResourceDetails</code>(例如<code>ClientCredentialsResource</code>,对于“client_credentials”授权类型)。对于需要用户授权的授权类型,还有一个其他属性:</p> <ul> <li><code>userAuthorizationUri</code>:如果用户需要授权访问资源,则用户将被重定向到的uri。请注意,这并不总是需要,具体取决于支持哪个OAuth 2配置文件。</li> </ul> <p>在XML中有一个<code><resource/></code>可以用来创建类型的bean的元素<code>OAuth2ProtectedResourceDetails</code>。它具有匹配上述所有属性的属性。</p> <h3>客户端配置</h3> <p>对于OAuth 2.0客户端,使用简化配置<code>@EnableOAuth2Client</code>。这有两件事情:</p> <ul> <li> <p>创建一个过滤器bean(带有ID <code>oauth2ClientContextFilter</code>)来存储当前的请求和上下文。在需要在请求期间进行身份验证的情况下,管理重定向到和从OAuth认证uri。</p> </li> <li> <p><code>AccessTokenRequest</code>在请求范围中创建一个类型的bean 。授权代码(或隐式)授权客户端可以使用这种方式来保持与个别用户的状态相关。</p> </li> </ul> <p>过滤器必须连接到应用程序中(例如,使用 同一名称的Servlet初始化程序或<code>web.xml</code>配置<code>DelegatingFilterProxy</code>)。</p> <p>本<code>AccessTokenRequest</code>可以在使用 <code>OAuth2RestTemplate</code>这样的:</p> <pre> <code class="language-java">@Autowired private OAuth2ClientContext oauth2Context; @Bean public OAuth2RestTemplate sparklrRestTemplate() { return new OAuth2RestTemplate(sparklr(), oauth2Context); } </code></pre> <p>在会话范围中放置OAuth2ClientContext(为您),以保持不同用户的状态分开。没有了,您将不得不自己在服务器上管理等效的数据结构,将传入的请求映射到用户,并将每个用户与单独的实例相关联<code>OAuth2ClientContext</code>。</p> <p>在XML中有一个<code><client/></code>带有<code>id</code>属性的元素- 这是一个servlet的bean id,<code>Filter</code>在这种<code>@Configuration</code>情况下必须映射为一个<code>DelegatingFilterProxy</code>(具有相同名称)。</p> <h3>访问受保护的资源</h3> <p>一旦您提供了资源的所有配置,您现在可以访问这些资源。用于访问这些资源的建议的方法是通过使用<a href="http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html" rel="external nofollow" target="_blank" title="RestTemplate">所述<code>RestTemplate</code>在弹簧3引入</a>。Spring Security的OAuth提供<a href="http://projects.spring.io/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/OAuth2RestTemplate.java" rel="external nofollow" target="_blank">了</a>只需要提供一个实例的<a href="http://projects.spring.io/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/OAuth2RestTemplate.java" rel="external nofollow" target="_blank">RestTemplate的扩展</a><a href="http://projects.spring.io/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/resource/OAuth2ProtectedResourceDetails.java" rel="external nofollow" target="_blank"><code>OAuth2ProtectedResourceDetails</code></a>。要使用用户令牌(授权代码授权),您应该考虑使用创建一些请求和会话作用域上下文对象的<code>@EnableOAuth2Client</code>配置(或XML等效项<code><oauth:rest-template/></code>),以便不同用户的请求在运行时不会相冲突。</p> <p>作为一般规则,Web应用程序不应使用密码授权,因此<code>ResourceOwnerPasswordResourceDetails</code>如果可以支持,请避免使用<code>AuthorizationCodeResourceDetails</code>。如果您非常需要从Java客户端工作的密码授权,则使用相同的机制来配置您的凭据,并将凭据<code>OAuth2RestTemplate</code>添加到<code>AccessTokenRequest</code>(这是一个<code>Map</code>短暂的),而不是<code>ResourceOwnerPasswordResourceDetails</code>(在所有访问令牌之间共享)。</p> <h3>在客户端中持久化令牌</h3> <p>客户端并不<em>需要</em>坚持令牌,但它可以很好的为不要求用户每次在客户端应用程序重新启动时批准新的代金券授予。该<a href="http://projects.spring.io/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/ClientTokenServices.java" rel="external nofollow" target="_blank"><code>ClientTokenServices</code></a>接口定义了所必需的持续的OAuth为特定用户2.0的令牌的动作。提供了一个JDBC实现,但如果您希望实现自己的服务来将持久性数据库中的访问令牌和关联的身份验证实例存储起来,那么您可以使用。如果要使用此功能,您需要提供一个专门配置<code>TokenProvider</code>的<code>OAuth2RestTemplate</code>如</p> <pre> <code class="language-java">@Bean @Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES) public OAuth2RestOperations restTemplate() { OAuth2RestTemplate template = new OAuth2RestTemplate(resource(), new DefaultOAuth2ClientContext(accessTokenRequest)); AccessTokenProviderChain provider = new AccessTokenProviderChain(Arrays.asList(new AuthorizationCodeAccessTokenProvider())); provider.setClientTokenServices(clientTokenServices()); return template; } </code></pre> <h2>外部OAuth2提供商客户端的定制</h2> <p>一些外部OAuth2提供者(例如<a href="https://developers.facebook.com/docs/authentication" rel="external nofollow" target="_blank" title="Facebook">Facebook</a>)不能正确地实现规范,或者他们只是坚持使用旧版本的规范,而不是Spring Security OAuth。要在客户端应用程序中使用这些提供程序,您可能需要调整客户端基础架构的各个部分。</p> <p>以Facebook为例,应用程序中有一个Facebook功能<code>tonr2</code>(您需要更改配置以添加您自己的,有效的客户端ID和密码 - 它们很容易在Facebook网站上生成)。</p> <p>Facebook令牌响应在令牌的到期时间(它们使用<code>expires</code>而不是<code>expires_in</code>)中也包含不符合规定的JSON条目,因此,如果要在应用程序中使用到期时间,则必须使用自定义手动解码<code>OAuth2SerializationService</code>。</p>
  • Spring Boot 2.0 支持的Apache Camel 版本发布了_Apache Camel 2.22发布支持Spring Boot 2.0

    Spring Boot 2.0 支持的Apache Camel 版本发布了_Apache Camel 2.22发布支持Spring Boot 2.0Spring Boot 2.0 支持的Apache Camel 版本发布了_Apache Camel 2.22发布支持Spring Boot 2.0