最近燃料公司门户做了一个待办的汇总,从三个数据源拿数据汇总到首页,这三个数据源分别是域认证的接口,域认证的webservices,证书加密的接口,下面就这些接口,做一下简单总结
1 pfx证书的探索过程
0.1 提供的代码
private static string GetNewAccessToken()
{
var stsEndpoint = "https://***.com.cn/adfs/services/trust/13/certificatemixed";
var relayPartyUri = "https://*****i.com.cn";
var pfxFilePath = ConfigurationManager.AppSettings["pfxFilePath"];
Uri u = new Uri(relayPartyUri);
var certPath = System.IO.Path.Combine(pfxFilePath, "DVT2.pfx");
var certFile = File.OpenRead(certPath);
var certficateBytes = new byte[certFile.Length];
certFile.Read(certficateBytes, 0, (int)certFile.Length);
var cert = new X509Certificate2(certficateBytes, "DVT**&&90", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
var factory = new System.ServiceModel.Security.WSTrustChannelFactory(
new CertificateWSTrustBinding(SecurityMode.TransportWithMessageCredential), stsEndpoint
)
{ TrustVersion = TrustVersion.WSTrust13 };
if (factory.Credentials != null)
{
factory.Credentials.ClientCertificate.Certificate = cert;
}
var rst = new System.IdentityModel.Protocols.WSTrust.RequestSecurityToken
{
RequestType = RequestTypes.Issue,
KeyType = KeyTypes.Bearer,
AppliesTo = new System.IdentityModel.Protocols.WSTrust.EndpointReference(relayPartyUri),
KeySizeInBits = 0,
TokenType = "urn:ietf:params:oauth:token-type:jwt"
};
var genericXMLSecurityToken = factory.CreateChannel().Issue(rst) as System.IdentityModel.Tokens.GenericXmlSecurityToken;
string accessToken = genericXMLSecurityToken != null ? Encoding.UTF8.GetString(Convert.FromBase64String(genericXMLSecurityToken.TokenXml.InnerXml)) : string.Empty;
return accessToken;
}
1.1 pfx
百度百科对pfx的解释是:
公钥加密技术12号标准。
公钥加密技术12号标准(Public Key Cryptography Standards #12,PKCS#12)为存储和传输用户或服务器私钥、公钥和证书指定了一个可移植的格式。它是一种二进制格式,这些文件也称为PFX文件。开发人员通常需要将PFX文件转换为某些不同的格式,如PEM或JKS,以便可以为使用SSL通信的独立Java客户端或WebLogic Server使用
是一种Microsoft协议,使用户可以将机密信息从一个环境或平台传输到另一个环境或平台。使用该协议,用户就可以安全地将个人信息从一个计算机系统导出到另一个系统中。
1.2 WSTrustChannelFactory
在微软的代码段中有一段看不明白:
var factory = new System.ServiceModel.Security.WSTrustChannelFactory(
new CertificateWSTrustBinding(SecurityMode.TransportWithMessageCredential), stsEndpoint
)
{ TrustVersion = TrustVersion.WSTrust13 };
在了解了相关内容之后,我理解pfx只是一种加密的技术,加密出来的证书格式也不止这一种,但是了解到这里并不能帮助我理解到底是如何通过证书去获取信任包括代码中的stsEndpoint到底是什么意思,在检索WSTrustChannelFactory的过程中,我发现这是和WCF密切相关的一个允许客户端直接与 WS-Trust 颁发者进行通信的对象
WSTrustChannelFactory 和 WSTrustChannel
1.3 WS-Trust
百度百科的解释:
WS-Trust是WS-*规范族中的一员,也是OASIS(Organization for the Advancement of Structured Information Standards)其中的一项标准。
它对WS-Security规范提供了一些扩展,专门处理有关安全tokens的发布,整新和验证,确保各方参与者的互操作处在一个可信任的安全数据交换环境中。
WS-Trust规范发起于一些有代表性的公司,最后于2007年3月被OASIS核准通过并作为一项标准发布。
通过使用WS-Trust中定义的这些扩展规范,可以确保工作在Web服务框架中的Web应用之间的通信是安全的。
上面这篇文章是对WS-TRUST的全面解析,
消费者向STS请求token的请求结构
我觉得非常有用的是这两段:
The AppliesTo field is optional and enables the requester to specify the endpoint to which the returned token will be sent. In some cases, the STS is configured to know what token type must be returned for a specific endpoint.
If the AppliesTo and TokenType fields are both present in the request, the precedence goes to the AppliesTo field; that is, if the STS knows that the endpoint uses a different token type than the one specified in the TokenType field, it ignores the TokenType field and returns the token that is used by the endpoint. This assumes that the STS is the only party knowing what token types are supported by the providers' endpoints. The advantage of this mechanism is that each consumer doesn't have to maintain the whole list of supported token types and endpoints.
所以我们知道endpint 这个终端在待办开发里面,就指的微软的WCF服务,STS会判断这个终端用的是哪种令牌然后返回这个令牌。
STS返回令牌的结构是:
正好也对应了这一段:
var genericXMLSecurityToken = factory.CreateChannel().Issue(rst) as System.IdentityModel.Tokens.GenericXmlSecurityToken;
string accessToken = genericXMLSecurityToken != null ? Encoding.UTF8.GetString(Convert.FromBase64String(genericXMLSecurityToken.TokenXml.InnerXml)) : string.Empty;
return accessToken;
即向STS建立channel,发送请求令牌的请求结构,然后在返回的xml中,提取需要的token,因为微软的服务用的是WCF,SOAP所使用的都是xml。在检索WS-TRUST时,最多匹配到的中文结果都是与WCF相关的,也侧面推测出了微软的服务就是用WCF做得。
1.4 小结
在这两个小时的了解过程中,并没有执着于对这段代码的技术分析,而是主要了解背后的逻辑和协议,如果以后再遇到类似的情况,我觉得再做深入的探索也不迟,知道对目前的我来说,现在的了解已经满足了我的求知欲。
2 windows域认证
在web页面写js 的时候,我同时遇到了windows的域和js的域问题。
同时我们都知道web里面认证分为windows认证和form认证,在部署了AD的环境下,使用windows认证其实更方便,因为开发者不需要编写登录页面和登录逻辑,但是这部分我有一个疑惑,就是如果我想拿到域登录用户的个人凭证,拿着这个凭证去访问其他的资源,比如请求某些数据源,这些操作是否只能在客户端完成,因为在服务端是没法完整拷贝整个用户凭证的,目前我遇到的具体的问题就是不能在服务端拿到用户的密码。
2.1 windows域
域英文叫DOMAIN——域(Domain)是Windows网络中独立运行的单位,域之间相互访问则需要建立信任关系(即Trust Relation)。信任关系是连接在域与域之间的桥梁。当一个域与其他域建立了信任关系后,2个域之间不但可以按需要相互进行管理,还可以跨网分配文件和打印机等设备资源,使不同的域之间实现网络资源的共享与管理。
域既是 Windows 网络操作系统的逻辑组织单元,也是Internet的逻辑组织单元,在 Windows 网络操作系统中,域是安全边界。域管理员只能管理域的内部,除非其他的域显式地赋予他管理权限,他才能够访问或者管理其他的域;每个域都有自己的安全策略,以及它与其他域的安全信任关系。
2.2 js域
javascript处于安全方面的考虑,不允许跨域调用其他页面的对象,javascript的同源策略:a.com下的js无法操作b.com或者c.a.com下的对象
具体的是否跨域的判断可以看下表:
具体跨域的解决方案可以在下面的链接里面了解
2.3 IE中跨域的处理
IE中有一个信任站点的概念,假如a.com 和b.com的网站属于同一个windows域,那么在IE上把他们都添加到信任站点可以实现免登陆,如果在IE信任站点的高级配置里面,允许跨域浏览窗口和框架+允许跨域请求数据源,那么就相当于放开了js 的同源策略,即在a.com的脚本可以操作b.com的对象和数据源。
详细的图文设置如下:
3.1 webservice接口
3.1 webservice允许get、post网络请求
在webconfig里面添加
<system.web>
<webServices>
<protocols>
<add name="HttpPost"/>
<add name="HttpGet"/>
</protocols>
</webServices>
</system.web>
3.2 webservice 允许跨域访问
把跨域文件放到web服务器,跨域xml示例:
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from>
<domain uri="*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
4 总结
虽然写到了总结,但是还有有一个遗留问题,就是保存域用户的身份凭证,在浏览器里我看到一些cookie应该是用做认证用的,但是还没详细的去研究,下午搞这个。