openid/python-openid

Reduce anxiety over TypeURIMismatch

RayPlante opened this issue · 2 comments

This suggestion arose while I was attempting to understand an error message in the log while verifying an authentication response:

Error attempting to use stored discovery information: 
<openid.consumer.consumer.TypeURIMismatch: Required type http://specs.openid.net/auth/2.0/signon 
not found in ['http://specs.openid.net/auth/2.0/server', 'http://openid.net/srv/ax/1.0'] for endpoint <openid.consumer.discover.OpenIDServiceEndpoint 
server_url='https://wire.ncsa.uiuc.edu/openid/provider' claimed_id=None local_id=None 
canonicalID=None used_yadis=True >>

This occurs when I had previously used an OP Identifier as the claimed ID when initializing the authentication. (An OP Identifier is used when user will select an identity at the OP login page; see use of identity_select in spec). Verification fails because the information cached during initialization based on the OP Identifier, while the verification step expects it to be based on the user's OP-local ID. This is detected (in consumer.py:1004) when cached endpoint does not include http://specs.openid.net/auth/2.0/signon among its type_uris, indicating a v2 OpenID.

This is is not a big deal as the verification code (after printing the above error message) turns right around and does a re-discovery on the user's claimed_id, and verification completes successfully. However, I noticed during my googling that others have been puzzled by this (apparently while chasing down perhaps unrelated problems). Indeed, the use of the word "Error" and the citing of the Exception, TypeURIMismatch, suggests that something is actually wrong when I don't think that is actually the case.

(My testing indicates that attempting to use the info cached for the OP Identifier during verification causes verification of the message signature to fail. Is this correct behavior?)

I would then suggest the following change to consumer.py near line 924:

    if not endpoint:
        oidutil.log('No pre-discovered information supplied.')
        endpoint = self._discoverAndVerify(to_match.claimed_id, [to_match])
    ############## v INSERT HERE v ######################
    elif endpoint.isOPIdentifier():
        oidutil.log('Pre-discovered information based on OP-ID; need to rediscover.')
        endpoint = self._discoverAndVerify(to_match.claimed_id, [to_match])
    ############## ^ INSERT HERE ^ ######################
    else:
        # The claimed ID matches, so we use the endpoint that we
        # discovered in initiation. This should be the most common
        # case.
        try:
            self._verifyDiscoverySingle(endpoint, to_match)
        except ProtocolError, e:
            oidutil.log(
                "Error attempting to use stored discovery information: " +
                str(e))

+1

This repo is being archived. Closing issue.