网络负载均衡环境下wsHttpBinding+Message Security+Windows Authentication的常见异常
提高Windows Communication Foundation (WCF) 应用程序负载能力的方法之一就是通过把它们部署到负载均衡的服务器场中. 其中可以使用标准的负载均衡技术, Windows 网络负载均衡(NLB)的软件(例如 Application Request Routing), 或者硬件(F5)实现NLB的功能. 随着这些NLB场景变得越来越复杂, 对WCF的架构带来了越来越多的挑战. 本文仅对wsHttpBinding+Message Security+Windows Authentication在NLB的环境下最常见的文件进行讨论..
介绍 :
通过阅读本文, 您可以了解到:
- NLB下wsHttpBinding+Message Security+Windows Authentication常见的异常.`
- WCF Message Security的Windows Authentication是如何进行的.
- 提供几种典型的WCF Security的配置方式.
预备知识 :
WCF wsHttpBinding默认采用Message Security模式. 相比Transport Security模式,它有很多优点。例如:提供了End-to-End security, 允许选择性的加密部分消息,与传输协议无关可以用于任何传输协议,提供更多的安全选择。更多内容可以参考 :
http://msdn.microsoft.com/en-us/library/ff648863.aspx
http://msdn.microsoft.com/en-us/library/ms733137(v=vs.110).aspx
Message Security 下有多种客户端验证方式。 其中Windows authentication是比较常用的Credential Type,并且是默认值。更多内容可以参考:
http://msdn.microsoft.com/en-us/library/ms731346(v=vs.110).aspx
常见问题 :
在Standalone的服务器上WCF Security能够很好的工作. 但是在NLB的环境上, 由于错误的配置方式, 可能会遇到下面的常见错误 :
WsHttpBinding+Message Security+Windows Authentication是如何工作的 :
要了解这两个错误是如何发生的, 首先需要了解正常情况下wsHttpBinding Message Security是如何进行Windows 验证的.
一般情况下, wsHttpBinding按照SPNEGO来引导一个SecurityContextToken(SCT)的生成, 并且将SCT缓存到服务器端. STCs 是基于对称密钥生成的,能够非常有效的签注/加密(signing/encrypting)消息。 当确定客户端会向服务器端发送多次请求的时候,这是一种非常好的提供效率的方式。通过观察WCF TRACE,一般来说会看到这样的过程。首先客户端和服务端生成一个SCT,然后进行一个SPNEGO的过程(有可能是多次请求才能完成),最后客户端和服务端交换SCT并且使用SCT加密WCF的调用。
下面比较详细的列举出整个步骤
- 客户端首先进行SP-Nego 握手, 这个过程完成后会生成一个SCT。
1) 客户端先发送一个Request Security Token(RST)。RST的目的是生成SP-Nego TokenType,它包含了一个SP-Nego块.
2) 服务端返回一个Request Security Token Response (RSTR).
3) 如果需要的话,客户端会将RSTR再次发送给服务端.
4) 服务端将一个对称密钥包裹在STC里, 又将STC包裹在Request Security Token Response Collection (RSTRC). 然后把RSTRC发送给客户端.
一般来说3)和4)可能会发生多次, 一般情况下可能会有4次, 2次客户端2次服务端.
- 客户端向服务端请求另外一个SCT用于消息层面的security。这个SCT是一个长生命是周期,并且真正代表了客户端和服务端之间的session key.
1) 客户端用SCT加注并且加密RST, 并把RST发送到服务端.
2) 服务器端用SCT加注并加密一个RSTR并发送会客户端. 这个RSTR中包含了一个SCT.
这里仅发生一次RST/RSTR.
- 客户端在得到 2 所产生的SCT之后,开始执行WCF调用。
1) 客户端使用上一步所得到的SCT来加密消息. 进行WCF调用.
2) 服务端执行完成之后, 使用同一的SCT来加密消息并返回给客户的. 在这里addressing headers会被签注, 消息体会被签注并且加密.
问题分析 :
问题一 :
The SecurityContextSecurityToken with context-id=urn:uuid:a02a1879-3297-4dee-8035-68eb30ed4195 (key generation-id=) is not registered.
at System.ServiceModel.Security.WSSecureConversation.SecurityContextTokenEntry.ReadTokenCore(XmlDictionaryReader reader, SecurityTokenResolver tokenResolver)
at System.ServiceModel.Security.WSSecurityTokenSerializer.ReadTokenCore(XmlReader reader, SecurityTokenResolver tokenResolver)
at System.IdentityModel.Selectors.SecurityTokenSerializer.ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver)
at System.ServiceModel.Security.ReceiveSecurityHeader.ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver, IList1 allowedTokenAuthenticators, SecurityTokenAuthenticator& usedTokenAuthenticator)
at System.ServiceModel.Security.ReceiveSecurityHeader.ReadToken(XmlDictionaryReader reader, Int32 position, Byte[] decryptedBuffer, SecurityToken encryptionToken, String idInEncryptedForm, TimeSpan timeout)
at System.ServiceModel.Security.ReceiveSecurityHeader.ExecuteFullPass(XmlDictionaryReader reader)
at System.ServiceModel.Security.StrictModeSecurityHeaderElementInferenceEngine.ExecuteProcessingPasses(ReceiveSecurityHeader securityHeader, XmlDictionaryReader reader)
at System.ServiceModel.Security.ReceiveSecurityHeader.Process(TimeSpan timeout)
at System.ServiceModel.Security.MessageSecurityProtocol.ProcessSecurityHeader(ReceiveSecurityHeader securityHeader, Message& message, SecurityToken requiredSigningToken, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
at System.ServiceModel.Security.SymmetricSecurityProtocol.VerifyIncomingMessageCore(Message& message, String actor, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
at System.ServiceModel.Security.MessageSecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
at System.ServiceModel.Channels.SecurityChannelListener1.ServerSecurityChannel1.VerifyIncomingMessage(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationState)
at System.ServiceModel.Channels.SecurityChannelListener1.SecurityReplyChannel.ProcessReceivedRequest(RequestContext requestContext, TimeSpan timeout)
at System.ServiceModel.Channels.SecurityChannelListener1.ReceiveRequestAndVerifySecurityAsyncResult.ProcessInnerItem(RequestContext innerItem, TimeSpan timeout)
at System.ServiceModel.Channels.SecurityChannelListener1.ReceiveItemAndVerifySecurityAsyncResult2.OnInnerReceiveDone()
at System.ServiceModel.Channels.SecurityChannelListener1.ReceiveItemAndVerifySecurityAsyncResult2.InnerTryReceiveCompletedCallback(IAsyncResult result)
at System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
at System.ServiceModel.Channels.InputQueue1.AsyncQueueReader.Set(Item item)
at System.ServiceModel.Channels.InputQueue1.Dispatch()
at System.ServiceModel.Channels.InputQueue1.OnDispatchCallback(Object state)
at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke2()
at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.OnSecurityContextCallback(Object o)
at System.Security.SecurityContext.Run(SecurityContext securityContext, ContextCallback callback, Object state)
at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke()
at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ProcessCallbacks()
at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.CompletionCallback(Object state)
at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.ServiceModel.Diagnostics.Utility.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
at System.Threading.IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped pOVERLAP)
这个错误在服务端和客户端均能看到, 但大多数情况下是在服务端发生, 并且将这一的错误饭或到了客户端. 这个错误的字面意思就是找不到SCT. 但是既然能够肯到STC的UUID, 那么说明这个SCT确实存在.
参照上面STC生成的过程可以看到, STC是服务端和客户端进过多次的交涉最终才能形成. 这个STC只能在这个服务端和客户端之间传递, 并不能分享给第三方. 这是出于安全的考虑.
这个问题最常见于NLB的环境中.如果NLB设备或者软件没有启用Sticky Session. 在有多台WCF服务器的情况下, 客户端发起的请求很有可能被转移到另外一台服务器上. 由于STC并不会被第三方获取, 那么另外一个服务器上不会有相同的SCT. 因此服务端会认为这个STC并没有被注册.
问题二:
<ExceptionType>System.ServiceModel.Security.SecurityNegotiationException, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>Cannot find the negotiation state for the context 'uuid-954e94c0-6e42-4816-b53f-bc75e18a9534-2'.</Message>
<StackTrace>
at System.ServiceModel.Security.NegotiationTokenAuthenticator`1.ProcessRequestCore(Message request)
at System.ServiceModel.Security.NegotiationTokenAuthenticator`1.NegotiationHost.NegotiationSyncInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
at System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext)
at System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext)
at System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result)
at System.ServiceModel.Dispatcher.ChannelHandler.OnAsyncReceiveComplete(IAsyncResult result)
at System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
at System.ServiceModel.Channels.InputQueue`1.AsyncQueueReader.Set(Item item)
at System.ServiceModel.Channels.InputQueue`1.Dispatch()
at System.ServiceModel.Channels.InputQueue`1.OnDispatchCallback(Object state)
at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke2()
at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.OnSecurityContextCallback(Object o)
at System.Security.SecurityContext.Run(SecurityContext securityContext, ContextCallback callback, Object state)
at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke()
at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ProcessCallbacks()
at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.CompletionCallback(Object state)
at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.ServiceModel.Diagnostics.Utility.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>
这个问题较多情况是发生在SPNego的阶段. 从上面介绍的步骤能够看到, SPNego的整个阶段很长,需要服务端和客户端进行多次的交流. 这这个交流的过程中, 任何一次请求被NLB递交到一个错误的服务器上都有可能造成这样的错误.
解决方案 :
造成上面问题的主要原因之一就是NLB的设备或者软件将客户端的请求递交到了一台错误的的服务器上. 要解决这一的问题, 最好的方法就是启用NLB上的Sticky Session. 在某些情形下, 如果NLB并不支持这种做法, 那么可以通过修改WCF配置来绕过这写问题.
为了解决第一个问题, 需要禁用Establishing Security Context. 禁用后, STC并不会被缓存起来, 也不会使用对称密钥, 而是改用非对称密钥, 而且每次都需要重新生成STC. 这种做法的副作用是降低WCF的性能.
<bindings> <wsHttpBinding> <binding name=”MyServiceBinding”> <security mode=”Message” > <message establishSecurityContext=”false” clientCredentialType=”Windows” /> </security> </binding> </wsHttpBinding> </bindings>
在解决第一个问题后, 仍然可能会遇到第二个问题. 因为默认情况下会服务端和客户端仍然会Negotiate Service Credential. 在这个过程中, 同样有可能会被NLB的行为中断从而引发问题. 可以通过禁用NegotiateServiceCredential来绕过这个问题.
<bindings> <wsHttpBinding> <binding name=”MyServiceBinding”> <security mode=”Message” >
<message establishSecurityContext=”false” NegotiateServiceCredential=”false” clientCredentialType=”Windows” /> </security> </binding> </wsHttpBinding> </bindings>
将属性设置为 true 需要客户端和服务支持 WS-Trust 和 WS-SecureConversation。 将属性设置为 false 时不需要 WS-Trust 或 WS-SecureConversation 受支持。对于 Windows 凭据,将此属性设置为 false 将导致基于 KerberosToken 的身份验证。 这要求客户端和服务都是 Kerberos 域的一部分。 此模式可与实现 OASIS Kerberos 令牌配置文件的 SOAP 堆栈交互操作。 将此属性为 true 会引起通过 SOAP 消息进行 SPNego 交换的 SOAP 协商. 如果将此属性设置为 false,并且将绑定配置为使用 Windows 作为客户端凭据类型,则必须将服务帐户与服务主体名称 (SPN) 相关联。 为此,请在 NETWORK SERVICE 帐户或 LOCAL SYSTEM 帐户下运行服务。 也可以使用 SetSpn.exe 工具为服务帐户创建一个 SPN。 不论何种情况,客户端都必须使用<servicePrincipalName> 元素中的正确 SPN,或者通过使用 EndpointAddress 构造函数来应用正确的 SPN。
除此之外, 还有下面的集中组合可以适用于NLB的环境中. 其中, BasicHttpBinding和wsHttpBinding均可以相互替换
• BasicHttpBinding - TransportCredentialOnly - Windows
• BasicHttpBinding - TransportCredentialOnly - Ntlm
• BasicHttpBinding - TransportWithMessageCredential - UserName
• BasicHttpBinding - TransportWithMessageCredential - Certificate
• wsHttpBinding - Transport - Ntlm
l BasicHttp – TransportCredentialOnly – Windows
Service – web.config
<basicHttpBinding> <binding name="basicN"> <security mode="TransportCredentialOnly"> <transport clientCredentialType="Windows"/> </security> </binding> </basicHttpBinding> <endpoint address="" binding="basicHttpBinding" contract="WindowsAuthTestService.IService1" bindingConfiguration="basicN" />
Client – app.config
<bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IService1"> <security mode="TransportCredentialOnly"> <transport clientCredentialType="Windows" /> </security> </binding> </basicHttpBinding> </bindings> <client> <endpoint address="http://localhost/WindowsAuthTestService/Service1.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1" name="BasicHttpBinding_IService1" /> </client>
l BasicHttp – TransportCredentialOnly – Ntlm
Service – web.config
<basicHttpBinding> <binding name="basicN"> <security mode="TransportCredentialOnly"> <transport clientCredentialType="Ntlm"/> </security> </binding> </basicHttpBinding> <endpoint address="" binding="basicHttpBinding" contract="WindowsAuthTestService.IService1" bindingConfiguration="basicN" />
Client – app.config
<bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IService1"> <security mode="TransportCredentialOnly"> <transport clientCredentialType="Ntlm" /> </security> </binding> </basicHttpBinding> </bindings> <client> <endpoint address="http://pupanda-win8.fareast.corp.microsoft.com/WindowsAuthTestService/Service1.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1" name="BasicHttpBinding_IService1" /> </client>
l BasicHttp – TransportWithMessageCredential – UserName
Service – web.config
<bindings> <basicHttpBinding> <binding name="b0"> <security mode="TransportWithMessageCredential"> <message clientCredentialType="UserName"/> </security> </binding> </basicHttpBinding> </bindings> <serviceBehaviors> <behavior name="sb"> <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="true"/> <serviceCredentials> <userNameAuthentication userNamePasswordValidationMode="Windows" /> <serviceCertificate findValue="11 12 32 12" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySerialNumber"/> </serviceCredentials> </behavior> </serviceBehaviors>
Client – app.config
<bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IService1"> <security mode="TransportWithMessageCredential" /> </binding> </basicHttpBinding> </bindings> <client> <endpoint address="https://server/TransportMessageService/Service1.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1" name="BasicHttpBinding_IService1" /> </client>
BasicHttp – TransportWithMessageCredential – Certificate
Service – web.config
<basicHttpBinding> <binding name="b0"> <security mode="TransportWithMessageCredential"> <message clientCredentialType="Certificate"/> </security> </binding>
Client – app.config
<bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IService1"> <security mode="TransportWithMessageCredential"> <message clientCredentialType="Certificate"/> </security> </binding> </basicHttpBinding> </bindings> <client> <endpoint address="https://server2/TransportMessageService/Service1.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1" behaviorConfiguration="cl" contract="ServiceReference1.IService1" name="BasicHttpBinding_IService1" /> </client> <behaviors> <endpointBehaviors> <behavior name="cl"> <clientCredentials> <clientCertificate findValue="31 7c d9 40 b5 ac b0 8e 99 99 00 00 12" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySerialNumber"/> </clientCredentials> </behavior> </endpointBehaviors> </behaviors>
l wsHttpBinding – Transport – Ntlm
Service – web.config
<wsHttpBinding> <binding name="wsTransportBinding"> <security mode="Transport"> <transport clientCredentialType="Ntlm" /> </security> </binding> </wsHttpBinding> Client – app.config <bindings> <wsHttpBinding> <binding name="WSHttpBinding_IService1"> <security mode="Transport"> <transport clientCredentialType="Ntlm" /> </security> </binding> </wsHttpBinding> </bindings> <client> <endpoint address="https://server/TransportMessageService/Service1.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1" name="WSHttpBinding_IService1"> <identity> <servicePrincipalName value="host/pupanda-server.fareast.corp.microsoft.com" /> </identity> </endpoint> </client>
参考文档 :
http://msdn.microsoft.com/en-us/library/vstudio/hh273122(v=vs.100).aspx
http://blogs.msdn.com/b/socaldevgal/archive/2007/08/15/why-is-wshttpbinding-secure-by-default-how-does-it-work.aspx
http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512/ws-secureconversation-1.3-os.html
网络负载均衡环境下wsHttpBinding+Message Security+Windows Authentication的常见异常的更多相关文章
- 解决网站在负载均衡环境下SESSION丢失的问题
在WEB场中,动态网页往往会因为几台主机做了负载而产生SESSION丢失的问题,网上也有很多的介绍,我这里只将我经历的过程给大家分享一下: 系统要运行在负载平衡的 Web 场环境中,而系统配置文件 ...
- Windows 2008 R2_NLB网络负载均衡(图文详解)(转)
目录 前言 软件环境 DNS域名服务器 DNS服务器原理 DNS域名空间 DNS区域 DNS服务器的类别 DNS查询模式 缓存文件 配置DNS服务器 DNS服务的应用 新建子域 在DNS正向解析中新建 ...
- Linux学习10-CentOS搭建nginx负载均衡环境
前言 当自己的web网站访问的人越来越多,一台服务器无法满足现有的业务时,此时会想到多加几台服务器来实现负载均衡. 网站的访问量越来越大,服务器的服务模式也得进行相应的升级,怎样将同一个域名的访问分散 ...
- windows网络服务之配置网络负载均衡(NLB)群集
O首页51CTO博客我的博客 搜索 每日博报 社区:学院论坛博客下载更多 登录注册 家园 学院 博客 论坛 下载 自测 门诊 周刊 读书 技术圈 曾垂鑫的技术专栏 http:// ...
- 负载均衡配置下的不同服务器【Linux】文件同步问题
负载均衡配置下的不同服务器[Linux]文件同步问题2017年04月13日 22:04:28 守望dfdfdf 阅读数:2468 标签: linux负载均衡服务器 更多个人分类: 工作 问题编辑版权声 ...
- Nginx+Keepalived(双机热备)搭建高可用负载均衡环境(HA)
原文:https://my.oschina.net/xshuai/blog/917097 摘要: Nginx+Keepalived搭建高可用负载均衡环境(HA) http://blog.csdn.ne ...
- Nginx+Keepalived(双机热备)搭建高可用负载均衡环境(HA)-转帖篇
原文:https://my.oschina.net/xshuai/blog/917097 摘要: Nginx+Keepalived搭建高可用负载均衡环境(HA) http://blog.csdn.ne ...
- Windows平台分布式架构实践 - 负载均衡(下)
概述 我们在上一篇Windows平台分布式架构实践 - 负载均衡中讨论了Windows平台下通过NLB(Network Load Balancer) 来实现网站的负载均衡,并且通过压力测试演示了它的效 ...
- 为什么基于Windows Server 2008 R2的网络负载均衡(NLB)配置的时候总会报错“主机不可访问”?
配置基于Windows的网络负载均衡是很容易的,操作也很简单,点点鼠标基本上就能完成,但是在进行节点(真实服务器)操作的过程中有时候会遇到一些主机不可访问的报错信息.这个又是为什么呢? Figure ...
随机推荐
- oracle_PLSQL 快捷键使用技巧
PLSQL 快捷键使用技巧 2012-01-17 09:32:50标签:PLSQL PLSQL 编程工具快捷设置 PLSQL使用技巧 PLSQL 快捷键 oracle PLSQL 最近在开发过程中,遇 ...
- linux_根据关键词_路径下递归查找code
1:进入想查找的项目根目录 2:根据关键词查找 find . -name "*" |xargs grep -F '10.26'
- 【Linux】Vim编辑器-批量注释与反注释
[-] vim编辑器---批量注释与反注释 方法一 块选择模式 插入注释 取消注释 方法二 替换命令 批量注释 取消注释 实例演示 vim编辑器---批量注释与反注释 在使用vim编写代码的时候, ...
- java_windows下修改eclipse的默认编码
windows下修改eclipse的默认编码 windows下一般系统编码为 GB2312(中文版的windows), 由于我比较喜欢utf8格式的编码,现将修改方式和大家分享 如果要使新建立工程 ...
- Jquery AJAX POST与GET之间的区别
1:GET访问 浏览器 认为 是等幂的就是 一个相同的URL 只有一个结果[相同是指 整个URL字符串完全匹配]所以 第二次访问的时候 如果 URL字符串没变化 浏览器是 直接拿出了第一次访问的结果 ...
- Windows Azure VM两shut down 道路
今天调查Azure当价格,找到下面的语句,来自http://azure.microsoft.com/en-us/pricing/details/virtual-machines/ * If my de ...
- Visual Studio 2015 & C#6.0 试用报告,持续更新。
昨天早上看到了.net开源的消息,我是非常兴奋的,毕竟局限于Windows的.NET经常被人唾弃.VB暂且不提,C#常年被人指责跨平台性不佳,我也是无能为力.即使有Mono等第三方跨平台工程,.NET ...
- hdu 1059 Dividing 多重背包
点击打开链接链接 Dividing Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- MVC无刷新分页
MVC无刷新分页(即局部刷新,带搜索,页数选择,排序功能) 我查看了很多网站,大部分评论分页都是局部刷新的,可大部分电商商品展示分页都是有刷新页面的,于是我便做了一个商品展示无刷新分页的例子.接下 ...
- Scala 的 Web 框架 Lift 开始 3.0 版本开发
Scala 的 Web 框架 Lift 开始 3.0 版本开发 http://demo.liftweb.net/ http://liftweb.net/download Lift 框架在不断的成长和改 ...