Pergunta

Descrição geral

Implementei um OP (OpenID Provider), usando DotNetOpenAuth.Estou testando-o em exemplos de RPs (partes confiáveis), como o login OpenID do Drupal e o OpenIdRelyingPartyWebForms projeto no DotNetOpenAuth's Samples solução.

O problema é que, pelo que sei, quando um navegador salta contra meu OP e envia uma solicitação de "autenticação bem-sucedida" (mode: id_res, claimed_id: smth, etc.) de volta ao RP, o RP não tenta realizar uma solicitação do lado do servidor ao OP e pergunta se realmente autenticou o usuário.Posso ver que há um openid.sig assinatura retornada do OP, mas, novamente, não vejo como o RP poderia verificá-la, já que não trocou chaves com o OP.

Então a questão é: Existe alguma configuração do lado do OP que eu possa ativar para tornar o fluxo de trabalho seguro?

Detalhes técnicos

Estou usando o Wireshark para detectar o tráfego HTTP no lado RP.Não há HTTPS, então posso ver e ler todas as mensagens.Abaixo você pode ver o que acontece exatamente. B = Navegador, OP = Provedor OpenID, PR = Parte Confiante.Os nomes de domínio são substituídos por *.example.com.

  1. (B -> PR) O usuário tenta visitar um recurso exclusivo para membros na terceira parte confiável.Ele insere o endpoint OP que o navegador publica no RP.

    identificador_aberto: http://OP.example.com/OpenId/Provider.aspx?xrds

  2. (RP –> OP –> RP) RP emite uma solicitação do lado do servidor para meu OP que retorna um documento XRDS.Não consigo ver nada semelhante à troca de chaves secretas aqui.

    <?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) Parte confiável 302-redireciona o usuário para OP's /OpenId/Provider.aspx?[params] URL, onde os parâmetros são os seguintes:

    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) O provedor autentica o usuário e o redireciona 302 de volta ao RP com os seguintes parâmetros de URL:

    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) O RP executa uma solicitação HTTP do lado do servidor para o OP.Não há transferência de dados, apenas uma solicitação GET para o URL de identidade do usuário adquirido anteriormente.A propósito, por que faz esse pedido?

    GET /OpenId/User.aspx/2925 HTTP/1.1
    
  6. (OP -> PR) O OP responde com outro documento 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) É isso.O usuário está autorizado e o RP mostra a ele o recurso exclusivo para membros.

Foi útil?

Solução

Os PRs podem operar em com estado ou apátrida modos (também conhecidos como modos inteligente e burro, respectivamente).Confira fluxogramas de rede para cada.

Há uma troca única de chaves entre RP e OP, desde que o RP esteja operando em modo stateful.Se estiver no modo sem estado, você verá uma mensagem do RP para o OP após cada autenticação para verificar a assinatura da asserção.

Em relação à sua pergunta nº 5 (a solicitação HTTP HEAD para o identificador reivindicado), este é o RP DotNetOpenAuth verificando se o OP é autoritativo para a identidade que está afirmando.Como já havia extraído esse URL, o cache entra em ação e evita a transferência de conteúdo.

Outras dicas

Estou me sentindo estúpido agora, perdi algo básico - lá é uma troca de chaves entre RP e OP, mas acontece apenas uma vez, e então a chave é armazenada em cache em ambos os lados por algum tempo.

Portanto, minha implementação do provedor OpenID é segura :)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top