djoos / EscapeWSSEAuthenticationBundle

Symfony bundle to implement WSSE authentication
http://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html
137 stars 59 forks source link

InvalidArgumentException: This token has no "nonce" attribute. #57

Closed Whipstickgostop closed 8 years ago

Whipstickgostop commented 9 years ago

Latest commit is requesting a Nonce attribute in lowercase, and doing so results in expected failure to authenticate. Not doing so results in the error above. Rolling back to commit #e1569417f094d9f89e3c40a4b39fcb0f41b62d4d resolves the issue.

djoos commented 9 years ago

Hi @michaelmarlow,

would you be able to elaborate this a bit more? I'm not able to reproduce this issue... Are you making use of any custom provider/listener/...?

Thanks in advance for your feedback!

Kind regards, David

Whipstickgostop commented 9 years ago

No custom provider. I did recently update to Symfony 2.6 (from 2.4), but again, it works fine (even on 2.6) when I roll back to e156941.

Token format (HTTP_X-WSSE header)t: 'UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s"'

Full stack trace: 7) \APIBundle\Tests\Controller\QuoteControllerTest::testPostQuote InvalidArgumentException: This token has no "nonce" attribute.

.../vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php:211 .../vendor/escapestudios/wsse-authentication-bundle/Escape/WSSEAuthenticationBundle/Security/Core/Authentication/Provider/Provider.php:66 .../vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/AuthenticationProviderManager.php:74 .../vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/AccessListener.php:65 .../vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall.php:69 .../vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php:59 .../vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php:164 .../vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php:53 .../vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php:167 .../vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php:112 .../app/bootstrap.php.cache:3009 .../app/bootstrap.php.cache:2982 .../app/bootstrap.php.cache:3131 .../app/bootstrap.php.cache:2376 .../vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Client.php:81 .../vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Client.php:111 .../vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Client.php:327 .../APIBundle/Tests/Controller/QuoteControllerTest.php:66

djoos commented 9 years ago

Hi @michaelmarlow,

the token has changed a lot from < 2.0.0 to 2.0.0. Would you mind sharing me some code of the testPostQuote? (if possible)

Thanks in advance!

Kind regards, David

Whipstickgostop commented 9 years ago

No problem. Here's the token generator and the relevant call from testPostQuote.

class WsseToken
{
    public static function makeNonce() {
        $chars = "123456789abcdefghijklmnopqrstuvwxyz";
        $random = "" . microtime();
        $random .= mt_rand();
        $mi = strlen($chars) - 1;
        for ($i = 0; $i < 10; $i++) {
            $random .= $chars[mt_rand(0, $mi)];
        }
        $nonce = md5($random);
        return $nonce;
    }

    public static function makeToken($username, $password) {
        $nonce = self::makeNonce();
        $ts = date('c');
        $digest = base64_encode(sha1($nonce.$ts.$password, true));
        $nonce = base64_encode($nonce);
        return sprintf('UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s"',
            $username, $digest, $nonce, $ts);
    }
}
public function getAuthHeaders()
    {
        $token = WsseToken::makeToken('bob', 'buffalo');
        return array(
            'HTTP_Authorization' => 'WSSE profile="UsernameToken"',
            'HTTP_X-WSSE' => $token
        );
    }

Call from testPostQuote():

$client = static::createClient();

        $request = array(
           ...
        );
        $crawler = $client->request('POST', '/api/quotes', $request, array(), $this->getAuthHeaders());

        $response = $client->getResponse();
        $this->assertJsonResponse($response, 200);

...
djoos commented 9 years ago

Hi @michaelmarlow,

I finally had the time to have a deeper look into the issue you are experiencing. It seems that the provider is trying to get the 'nonce' attribute (EscapeWSSEAuthenticationBundle/Security/Core/Authentication/Provider/Provider.php), but the attribute hasn't been set. This is actually done in the listener (EscapeWSSEAuthenticationBundle/Security/Http/Firewall/Listener.php), so I'm wondering whether you are definitely not using a custom listener.

Could you check the escape_wsse_authentication-section of your app/config/security.yml?

Thanks in advance for your feedback!

Kind regards, David

Whipstickgostop commented 9 years ago

This was in config.yml rather than security.yml:

# Escape WSSE authentication configuration
escape_wsse_authentication:
    authentication_provider_class: Escape\WSSEAuthenticationBundle\Security\Core\Authentication\Provider\Provider
    authentication_listener_class: Escape\WSSEAuthenticationBundle\Security\Http\Firewall\Listener
    authentication_entry_point_class: Escape\WSSEAuthenticationBundle\Security\Http\EntryPoint\EntryPoint
    authentication_encoder_class: Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder

And here is the relevant firewall:

wsse_secured:
            provider: apibundle
            pattern:  ^/api/(?!doc/)
            wsse:
                realm: "Secured with WSSE" #identifies the set of resources to which the authentication information will apply (WWW-Authenticate)
                profile: "UsernameToken" #WSSE profile (WWW-Authenticate)
                lifetime: 300
                encoder: #digest algorithm
                    algorithm: sha1
                    encodeHashAsBase64: true
                    iterations: 1

Thanks for your continued assistance.

djoos commented 9 years ago

Hi @michaelmarlow,

sorry: I incorrectly mentioned security.yml; it was meant to be config.yml.

Would you mind checking whether your Escape\WSSEAuthenticationBundle\Security\Http\Firewall\Listener definitely has $token->setAttribute('nonce', $wsseHeaderInfo['Nonce']); on line 79?

The issue you're running into, with the config you've provided, doesn't seem to make lots of sense...

Thanks in advance for your feedback!

Kind regards, David

Whipstickgostop commented 9 years ago

Yup, that line is indeed there.

vodoo22 commented 8 years ago

Hey please, did u find a solution to this exception?

djoos commented 8 years ago

Hi guys,

are you still experiencing this issue with the latest version of this bundle?

Thanks in advance!

Kind regards, David

Whipstickgostop commented 8 years ago

Sorry for the delayed response. I don't remember when I updated to ~2.3, but it has been fixed for awhile. Thanks!