如何在 Internet Explorer 7.0 中使用 Windows CardSpace

Download sample

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 页,并在该页中进行处理。 按下提交按钮后将显示标识选择器。

对象元素的重要元素包括:

元素 说明

type="application/x-informationcard"

指示浏览器显示标识选择器对象。

param name="tokenType"

控制标识选择器发出的令牌类型,在本示例中为 SAML 1.0 令牌。

param name="issuer"

提供标识的标识提供方的 URL。 在本示例中为调用内置的自行颁发提供方的硬连线 URI。

param name="requiredClaims"

依赖方请求用户提供包含特定声明的标识提供方(或用户)的令牌。 此处的示例是一组预定义的自行颁发(个人)卡的一部分。

按下此按钮后将显示 CardSpace 标识选择器。 这允许用户选择要提交的 CardSpace 标识。

选择 Windows CardSpce 卡

单击**“Yes, choose to send a card”(是,选择发送卡)**。 如果系统中没有卡,标识选择器将提供创建或导入卡的机会。

结合使用 Windows CardSpace 和 Internet Explorer 7.0

单击**“Create a new Personal card”(创建个人卡)**将显示创建自行颁发的卡的屏幕。

编辑 Windows CardSpace 卡

填写必填字段,选择一个图片,并为卡取一个名称,然后单击**“Save”(保存)**。 在创建满足所列声明的个人卡之后,发送该卡。

将 Windows CardSpace 卡发送到站点

加密卡数据将被发送到以下 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 页将加密令牌回显到屏幕。

结合使用 Windows CardSpace 和 Internet Explorer 7.0

根据需要激活标识选择器

本示例演示了更灵活地显示标识选择器的方法。 该示例使用了以下文件:

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>
元素 说明

MaximumClockSkew

60

可选。 客户端和服务器可以偏差的最大秒数。

CertificateThumbprint

<无>

可选。 用于对令牌进行解密的证书的指纹。 Token 类会自动查找证书。

StoreName

My

可选。 SSL 证书存储区的名称。 通常为“My”。

StoreLocation

LocalMachine

可选。 SSL 证书存储区的位置。 通常为“LocalMachine”。

IdentityClaimType

PPID

可选。 唯一标识用户所使用声明的声明类型的 URI。

在将令牌发布到登录页并解密后,现在我们可以看到声明值。

结合使用 Windows CardSpace 和 Internet Explorer 7.0

唯一地标识用户

本示例演示了如何使用 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 字符哈希值,可用于在数据库中唯一标识访问者。

结合使用 Windows CardSpace 和 Internet Explorer 7.0

若要更改标识唯一性所使用的声明,请将以下密钥添加到 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”;

词汇表

  • 标识提供方 — 断言有关主题(人员)的声明的代理(公司、网站、组织、自己)。

  • 标识选择器 — 标识选择器是一个对话框,其中会显示用户的不同数字标识并允许选择相关标识以提交给依赖方。

  • 依赖方 — 依赖于主题提供的声明的代理(网站、服务器或其他方)。

  • 主题 — 对标识做出声明的实体(用户)。 在向依赖方发布数字标识信息时主题会始终处于控制范围内。

Footer image

向 Microsoft 发送对本主题的评论。

版权所有 (C) 2007 Microsoft Corporation。保留所有权利。