一般说明

我实现了一个OP(OpenID Provider),使用 DotNetOpenAuth. 。我正在针对示例 RP(依赖方)对其进行测试,例如 Drupal 的 OpenID 登录和 OpenIdRelyingPartyWebForms DotNetOpenAuth 中的项目 Samples 解决方案。

问题是,据我所知,当浏览器弹回我的OP并发送“成功身份验证”请求时(mode: id_res, claimed_id: smth, 等)返回 RP,RP 不会尝试向 OP 执行服务器端请求并询问它是否确实对用户进行了身份验证。我可以看到有一个 openid.sig 签名从 OP 返回,但同样,我不知道 RP 如何验证它,因为它没有与 OP 交换密钥。

所以问题是: OP 端是否有一些设置可以使工作流程安全?

技术细节

我正在使用 Wireshark 嗅探 RP 端的 HTTP 流量。没有 HTTPS,因此我可以查看和阅读所有消息。下面您可以看到到底发生了什么。 = 浏览器, OP = OpenID 提供商, RP = 依赖方。域名替换为 *.example.com。

  1. (B –> RP) 用户尝试访问依赖方上的仅限会员的资源。他输入浏览器发布到 RP 的 OP 端点。

    openid_标识符: http://OP.example.com/OpenId/Provider.aspx?xrds

  2. (RP –> OP –> RP) RP 向我的 OP 发出服务器端请求,该请求返回 XRDS 文档。我在这里看不到任何类似于秘密密钥交换的内容。

    <?xml version="1.0" encoding="UTF-8"?>
    <xrds:XRDS
        xmlns:xrds="xri://$xrds"
        xmlns:openid="http://openid.net/xmlns/1.0"
        xmlns="xri://$xrd*($v*2.0)">
        <XRD>
            <Service priority="10">
                <Type>http://specs.openid.net/auth/2.0/server</Type>
                <Type>http://openid.net/extensions/sreg/1.1</Type>
                <URI>http://OP.example.com/OpenId/Provider.aspx</URI>
            </Service>
        </XRD>
    </xrds:XRDS>
    
  3. (RP –> B –> OP) 依赖方 302 - 将用户重定向到 OP /OpenId/Provider.aspx?[params] URL,其中参数如下:

    openid.claimed_id: http://specs.openid.net/auth/2.0/identifier_select
    openid.identity: http://specs.openid.net/auth/2.0/identifier_select
    openid.assoc_handle: {634730422000625000}{jkQC1Q==}{32}
    openid.return_to: http://RP.example.com/login.aspx?ReturnUrl=%2FMembersOnly%2FDefault.aspx&dnoa.receiver=ctl00_Main_OpenIdLogin1&dnoa.UsePersistentCookie=Session&dnoa.userSuppliedIdentifier=http%3A%2F%2FOP.example.com%2FOpenId%2FProvider.aspx%3Fxrds
    openid.realm: http://RP.example.com/
    openid.mode: checkid_setup
    openid.ns: http://specs.openid.net/auth/2.0
    openid.ns.sreg: http://openid.net/extensions/sreg/1.1
    openid.sreg.policy_url: http://RP.example.com/PrivacyPolicy.aspx
    openid.sreg.required: email,gender,postcode,timezone
    
  4. (OP –> B –> RP) 提供程序对用户进行身份验证,并使用以下 URL 参数将其 302 重定向回 RP:

    ReturnUrl: /MembersOnly/Default.aspx
    dnoa.receiver: ctl00_Main_OpenIdLogin1
    dnoa.UsePersistentCookie: Session
    dnoa.userSuppliedIdentifier: http://OP.example.com/OpenId/Provider.aspx?xrds
    openid.claimed_id: http://OP.example.com/OpenId/User.aspx/2925
    openid.identity: http://OP.example.com/OpenId/User.aspx/2925
    openid.sig: pWJ0ugjQATKGgRSW740bml9LDsSxFiJ+a9OLO6NlsvY=
    openid.signed: claimed_id,identity,assoc_handle,op_endpoint,return_to,response_nonce,ns.sreg,sreg.nickname,sreg.email
    openid.assoc_handle: {634730422000625000}{jkQC1Q==}{32}
    openid.op_endpoint: http://OP.example.com/OpenId/Provider.aspx
    openid.return_to: http://RP.example.com/login.aspx?ReturnUrl=%2FMembersOnly%2FDefault.aspx&dnoa.receiver=ctl00_Main_OpenIdLogin1&dnoa.UsePersistentCookie=Session&dnoa.userSuppliedIdentifier=http%3A%2F%2FOP.example.com%2FOpenId%2FProvider.aspx%3Fxrds
    openid.response_nonce: 2012-05-19T16:40:11ZSfsL4BK1
    openid.mode: id_res
    openid.ns: http://specs.openid.net/auth/2.0
    openid.ns.sreg: http://openid.net/extensions/sreg/1.1
    openid.sreg.nickname: user@OP.example.com
    openid.sreg.email: user@OP.example.com
    
  5. (RP –> OP) RP 向 OP 执行服务器端 HTTP 请求。没有传输任何数据,只是对先前获取的用户身份 URL 发出 GET 请求。顺便问一下,为什么它会提出这个要求呢?

    GET /OpenId/User.aspx/2925 HTTP/1.1
    
  6. (OP –> RP) OP 回复了另一个 XRDS 文件:

    <xrds:XRDS
        xmlns:xrds="xri://$xrds"
        xmlns:openid="http://openid.net/xmlns/1.0"
        xmlns="xri://$xrd*($v*2.0)">
        <XRD>
            <Service priority="10">
                <Type>http://specs.openid.net/auth/2.0/signon</Type>
                <Type>http://openid.net/extensions/sreg/1.1</Type>
                <URI>http://OP.example.com/OpenId/Provider.aspx</URI>
            </Service>
            <Service priority="20">
                <Type>http://openid.net/signon/1.0</Type>
                <Type>http://openid.net/extensions/sreg/1.1</Type>
                <URI>http://OP.example.com/OpenId/Provider.aspx</URI>
            </Service>
        </XRD>
    </xrds:XRDS>
    
  7. (RP –> B) 就是这样。用户获得授权,RP 向他显示仅限会员的资源。

有帮助吗?

解决方案

RP 可以在 有状态的 或者 无国籍的 模式(也分别称为智能模式和哑模式)。查看 每个网络的流程图.

如果 RP 在有状态模式下运行,则 RP 和 OP 之间存在一次性密钥交换。如果在无状态模式下,您将在每次身份验证后看到从 RP 到 OP 的消息,以验证断言的签名。

关于您关于#5 的问题(对声明的标识符的 HTTP HEAD 请求),这是 DotNetOpenAuth RP 检查 OP 对其所声明的身份是否具有权威性。由于它之前已拉取此 URL,因此缓存会启动并避免内容传输。

其他提示

我现在感觉很愚蠢,我错过了一些基本的东西——那里 RP和OP之间的密钥交换,但只发生一次,然后密钥在双方缓存一段时间。

所以我的 OpenID 提供程序的实现是安全的:)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top