如何在 Internet Explorer 7.0 中使用 Windows CardSpace
CardSpace 为用户提供了管理其数字标识的功能,使用 Internet Explorer 7.0,网站可以向用户请求数字标识。 下面的练习将演示使用 CardSpace 和 Internet Explorer 7.0 接受标识的步骤。 在本演练中,共有四个练习:
Hello, World!
根据需要激活标识选择器
访问安全令牌中的声明
唯一地标识用户
若要完成练习,必须进行网站配置。 使用示例文件夹中提供的安装批处理文件可以完成配置:
Setup.bat
有关安装网站的更多信息以及一些疑难解答提示,请参见安装 CardSpace 示例证书。
Hello World! 示例
Hello World 示例演示了使用标识选择器所需的 HTML 代码。 本示例使用了以下文件:
sample1.htm
login1.aspx
标识选择器通过使用 <object>
元素或二进制行为**对象进行显示。 最简便的方法是在 <form>
元素的正文中包括 <object>
元素,前者在提交表单时将激活标识选择器。 下面是 Sample1.htm 文件:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Sample 1</title>
</head>
<body>
<form id="form1" method="post" action="login1.aspx">
<button type="submit">Click here to sign in with your Information Card</button>
<object type="application/x-informationcard" name="xmlToken">
<param name="tokenType" value="urn:oasis:names:tc:SAML:1.0:assertion" />
<param name="issuer"
value="https://schemas.xmlsoap.org/ws/2005/05/identity/issuer/self" />
<param name="requiredClaims"
value="https://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname
https://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname
https://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
https://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier" />
</object>
</form>
</body>
</html>
<object>
元素的结果被直接发布到 login1.aspx 页,并在该页中进行处理。 按下提交按钮后将显示标识选择器。
对象元素的重要元素包括:
元素 | 说明 |
---|---|
|
指示浏览器显示标识选择器对象。 |
|
控制标识选择器发出的令牌类型,在本示例中为 SAML 1.0 令牌。 |
|
提供标识的标识提供方的 URL。 在本示例中为调用内置的自行颁发提供方的硬连线 URI。 |
|
依赖方请求用户提供包含特定声明的标识提供方(或用户)的令牌。 此处的示例是一组预定义的自行颁发(个人)卡的一部分。 |
按下此按钮后将显示 CardSpace 标识选择器。 这允许用户选择要提交的 CardSpace 标识。
单击**“Yes, choose to send a card”(是,选择发送卡)**。 如果系统中没有卡,标识选择器将提供创建或导入卡的机会。
单击**“Create a new Personal card”(创建个人卡)**将显示创建自行颁发的卡的屏幕。
填写必填字段,选择一个图片,并为卡取一个名称,然后单击**“Save”(保存)**。 在创建满足所列声明的个人卡之后,发送该卡。
加密卡数据将被发送到以下 Login1.aspx 页(下面显示的是用 C# 编写的页)。
<%@ Page Language="C#" Debug="true" ValidateRequest="false"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void Page_Load(object sender, EventArgs e) {
Label1.Text = Request.Params["xmlToken"];
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
The value of the token is:<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label></div>
</form>
</body>
</html>
加密卡数据被发送到以 VB.net 编码的 login1.aspx 页:
<%@ Page Language="VB" Debug="true" ValidateRequest="false"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
Label1.Text = Request.Params("xmlToken");
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
The value of the token is:<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label></div>
</form>
</body>
</html>
login1.aspx 页将加密令牌回显到屏幕。
根据需要激活标识选择器
本示例演示了更灵活地显示标识选择器的方法。 该示例使用了以下文件:
Sample2.htm
Login2.aspx
开发人员可能需要更灵活地安排和处理标识选择器的调用。 若要在更合适于特定应用程序的时间显示标识选择器,可以对 <object>
元素编写脚本以根据请求返回加密令牌。 下面的 Sample2.htm 文件演示了这种情形。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Sample 2</title>
<object type="application/x-informationcard" name="_xmlToken">
<param name="tokenType" value="urn:oasis:names:tc:SAML:1.0:assertion" />
<param name="requiredClaims"
value="https://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname
https://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname
https://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
https://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier" />
</object>
<script language="javascript">
function GoGetIt(){
var xmltkn=document.getElementById("_xmltoken");
var thetextarea = document.getElementById("xmltoken");
thetextarea.value = xmltkn.value ;
}
</script>
</head>
<body>
<form id="form1" method="post" action="login2.aspx">
<button name="go" id="go" onclick="javascript:GoGetIt();">Click here to get the token.</button>
<button type="submit">Click here to send the card to the server</button>
<textarea cols=100 rows=20 id="xmltoken" name="xmlToken" ></textarea>
</form>
</body>
</html>
将 <object>
元素放置在 HTML 文档的标头中,并在访问值属性时调用标识选择器。 本示例中的脚本将令牌 XML 放入允许开发人员在提交 <form>
之前查看内容的 <textarea>
元素中。
提示
文本区域中的令牌文本与 login2.aspx
页中的令牌文本不完全相同,这是因为浏览器取消了 XML 标记的显示。
获取对声明的访问
本示例演示如何使用 TokenProcessor.cs
访问发送到网站的卡中的声明。 该示例使用了以下文件:
Sample3.htm
Login3.aspx
app_code\TokenProcessor.cs
Web.config
若要从加密数据中获取声明,使用 ASP.NET 2.0 的开发人员可以使用本练习中提供的 TokenProcessor.cs
示例代码。 Token
类使用 Windows Communication Foundation (WCF) 类处理对令牌的所有解密和验证。 在发布的目标页中使用了 Token
类,在本示例中,目标页是指 login3.aspx 页,其 C# 代码为:
<%@ Page Language="C#" Debug="true" ValidateRequest="false" %>
<%@ Import Namespace="System.IdentityModel.Claims" %>
<%@ Import Namespace="Microsoft.IdentityModel.TokenProcessor" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void ShowError(string text) {
fields.Visible = false;
errors.Visible = true;
errtext.Text = text;
}
protected void Page_Load(object sender, EventArgs e)
string xmlToken;
xmlToken = Request.Params["xmlToken"];
if (xmlToken == null || xmlToken.Equals("")){
ShowError("Token presented was null");
}
else {
Token token= new Token(xmlToken);
givenname.Text = token.Claims[ClaimTypes.GivenName];
surname.Text = token.Claims[ClaimTypes.Surname];
email.Text = token.Claims[ClaimTypes.Email];
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Login Page</title>
</head>
<body>
<form id="form1" runat="server">
<div runat="server" id="fields">
Given Name:<asp:Label ID="givenname" runat="server" Text=""></asp:Label><br/>
Surname:<asp:Label ID="surname" runat="server" Text=""></asp:Label><br/>
Email Address:<asp:Label ID="email" runat="server" Text=""></asp:Label><br/>
</div>
<div runat="server" id="errors" visible="false">
Error:<asp:Label ID="errtext" runat="server" Text=""></asp:Label><br/>
</div>
</form>
</body>
</html>
其 Visual Basic .NET 代码为:
<%@ Page Language="VB" Debug="true" ValidateRequest="false" %>
<%@ Import Namespace="System.IdentityModel.Claims" %>
<%@ Import Namespace="Microsoft.IdentityModel.TokenProcessor" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
Protected Sub ShowError(ByVal text As String)
fields.Visible = False
errors.Visible = True
errtext.Text = text
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
Dim xmlToken As String
xmlToken = Request.Params("xmlToken")
If xmlToken = Nothing Or xmlToken.Equals("") Then
ShowError("Token presented was null")
Else
Dim token As New Token(xmlToken)
givenname.Text = token.Claims(ClaimTypes.GivenName)
surname.Text = token.Claims(ClaimTypes.Surname)
email.Text = token.Claims(ClaimTypes.Email)
End If
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Login Page</title>
</head>
<body>
<form id="form1" runat="server">
<div runat="server" id="fields">
Given Name:<asp:Label ID="givenname" runat="server" Text=""></asp:Label><br/>
Surname:<asp:Label ID="surname" runat="server" Text=""></asp:Label><br/>
Email Address:<asp:Label ID="email" runat="server" Text=""></asp:Label><br/>
</div>
<div runat="server" id="errors" visible="false">
Error:<asp:Label ID="errtext" runat="server" Text=""></asp:Label><br/>
</div>
</form>
</body>
</html>
若要从令牌中获取声明的值,请使用 Claims
属性。 这将以参数的形式获取声明的 URI,并作为 string
返回该值。 自行颁发的卡的 URI 将在本文档后面列出,但是为了节省时间,已在 SelfIssued
类中进行了预定义。
对于 Token
类,存在相应的配置数据。 在 Web.config 文件中,可以找到以下配置项:
<configuration>
<appSettings>
<add key="MaximumClockSkew" value="60"/>
<add key="CertifcateThumbprint" value="01234567890ABCDEFEDCBA01234567890ABCDEFEDCBA"/>
<add key="StoreName" value="My"/>
<add key="StoreLocation" value="LocalMachine"/>
<add key="IdentityClaimType"
value="https://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier"/>
</appSettings>
<configuration>
元素 | 值 | 说明 |
---|---|---|
|
60 |
可选。 客户端和服务器可以偏差的最大秒数。 |
|
<无> |
可选。 用于对令牌进行解密的证书的指纹。 Token 类会自动查找证书。 |
|
My |
可选。 SSL 证书存储区的名称。 通常为“My”。 |
|
LocalMachine |
可选。 SSL 证书存储区的位置。 通常为“LocalMachine”。 |
|
PPID |
可选。 唯一标识用户所使用声明的声明类型的 URI。 |
在将令牌发布到登录页并解密后,现在我们可以看到声明值。
唯一地标识用户
本示例演示了如何使用 Token
类唯一地标识用户。 本示例使用了以下文件:
Sample4.htm
Login4.aspx
app_code\TokenProcessor.cs
web.config
假设任何人都可以使用相同的声明值创建卡,那么能够使用自行颁发的声明值之外的其他值唯一地标识特定卡是很有必要的。 这可以通过计算卡的 UniqueID
来完成。 此 UniqueID
是颁发者的公钥和对该颁发者唯一的任何声明的哈希。 由于客户端与服务器之间的会话密钥是在首次通信时随机生成的,因此公钥对卡是唯一的。如果在多个站点使用相同的自行颁发的卡,则会为每个新的关联生成一个新的密钥对。 对于唯一声明,卡的私人标识符 (PPID)** 对该颁发者是唯一的。 UniqueID
属性可以为开发人员计算哈希值。 将代码添加到用 C# 编写的 login4.aspx 页:
<%@ Page Language="C#" Debug="true" ValidateRequest="false" %>
<%@ Import Namespace="System.IdentityModel.Claims" %>
<%@ Import Namespace="Microsoft.IdentityModel.TokenProcessor" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void ShowError(string text) {
fields.Visible = false;
errors.Visible = true;
errtext.Text = text;
}
protected void Page_Load(object sender, EventArgs e) {
string xmlToken;
xmlToken = Request.Params["xmlToken"];
if (xmlToken == null || xmlToken.Equals(""))
ShowError("Token presented was null");
else
{
Token token = new Token (xmlToken);
givenname.Text = token.Claims[SelfIssued.GivenName];
surname.Text = token.Claims[SelfIssued.Surname];
email.Text = token.Claims[SelfIssued.EmailAddress];
uid.Text = token.UniqueID;
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Login Page</title>
</head>
<body>
<form id="form1" runat="server">
<div runat="server" id="fields">
Given Name:<asp:Label ID="givenname" runat="server" Text=""></asp:Label><br/>
Surname:<asp:Label ID="surname" runat="server" Text=""></asp:Label><br/>
Email Address:<asp:Label ID="email" runat="server" Text=""></asp:Label><br/>
Unique ID:<asp:Label ID="uid" runat="server" Text=""></asp:Label><br/>
</div>
<div runat="server" id="errors" visible="false">
Error:<asp:Label ID="errtext" runat="server" Text=""></asp:Label><br/>
</div>
</form>
</body>
</html>
其 Visual Basic .NET 代码为:
<%@ Page Language="VB" Debug="true" ValidateRequest="false" %>
<%@ Import Namespace="System.IdentityModel.Claims" %>
<%@ Import Namespace="Microsoft.IdentityModel.TokenProcessor" %>
<script runat="server">
Protected Sub ShowError(ByVal text As String)
fields.Visible = False
errors.Visible = True
errtext.Text = text
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
Dim xmlToken As String
xmlToken = Request.Params("xmlToken")
If xmlToken = Nothing Or xmlToken.Equals("") Then
ShowError("Token presented was null")
Else
Dim token As New Token(xmlToken)
givenname.Text = token.Claims(ClaimTypes.GivenName)
surname.Text = token.Claims(ClaimTypes.Surname)
email.Text = token.Claims(ClaimTypes.Email)
uid.Text = token.UniqueID
End If
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Login Page</title>
</head>
<body>
<form id="form1" runat="server">
<div runat="server" id="fields">
Given Name:<asp:Label ID="givenname" runat="server" Text=""></asp:Label><br/>
Surname:<asp:Label ID="surname" runat="server" Text=""></asp:Label><br/>
Email Address:<asp:Label ID="email" runat="server" Text=""></asp:Label><br/>
Unique ID:<asp:Label ID="uid" runat="server" Text=""></asp:Label><br/>
</div>
<div runat="server" id="errors" visible="false">
Error:<asp:Label ID="errtext" runat="server" Text=""></asp:Label><br/>
</div>
</form>
</body>
</html>
结果会得到一个 base64 编码的 20 字符哈希值,可用于在数据库中唯一标识访问者。
若要更改标识唯一性所使用的声明,请将以下密钥添加到 Web.config,并将该值更改为其他声明 URI。
<add key="IdentityClaimType" value="https://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier"/>
关于实际的令牌
有关加密 XML 令牌的格式和用法的更多信息,请参考以下资源:
https://go.microsoft.com/fwlink/?LinkId=95951(可能为英文网页)
自行颁发的卡中的声明
给定名称 =“https://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname”;
电子邮件地址 =“https://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress”;
姓氏 =“https://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname”;
街道地址 =“https://schemas.xmlsoap.org/ws/2005/05/identity/claims/streetaddress”;
地区 =“https://schemas.xmlsoap.org/ws/2005/05/identity/claims/locality”;
省/自治区 =“https://schemas.xmlsoap.org/ws/2005/05/identity/claims/stateorprovince”;
邮政编码 =“https://schemas.xmlsoap.org/ws/2005/05/identity/claims/postalcode”;
国家/地区 =“https://schemas.xmlsoap.org/ws/2005/05/identity/claims/country”;
住宅电话 =“https://schemas.xmlsoap.org/ws/2005/05/identity/claims/homephone”;
其他电话 =“https://schemas.xmlsoap.org/ws/2005/05/identity/claims/otherphone”;
移动电话 =“https://schemas.xmlsoap.org/ws/2005/05/identity/claims/mobilephone”;
生日 =“https://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth”;
性别 =“https://schemas.xmlsoap.org/ws/2005/05/identity/claims/gender”;
PPID =“https://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier”;
网站 =“https://schemas.xmlsoap.org/ws/2005/05/identity/claims/website”;
词汇表
标识提供方 — 断言有关主题(人员)的声明的代理(公司、网站、组织、自己)。
标识选择器 — 标识选择器是一个对话框,其中会显示用户的不同数字标识并允许选择相关标识以提交给依赖方。
依赖方 — 依赖于主题提供的声明的代理(网站、服务器或其他方)。
主题 — 对标识做出声明的实体(用户)。 在向依赖方发布数字标识信息时主题会始终处于控制范围内。
版权所有 (C) 2007 Microsoft Corporation。保留所有权利。