Symfony FOSRestBundle + WSSE + FOSUserBundle -
i'm having trouble setting wsse security on symfony api. i'm following tutorial configure wsse on symfony fosrestbundle based on how create custom authentication provider
the issues :
how manage use fosuserbundle wsse (especially salt) ? don't want front retrieve salt of each user sends request.
i want make registration route anonymously reachable , each time try http request without sending x-wsse i'm getting error :
"message":"a token not found in securitycontext.", "class":"symfony\\component\\security\\core\\exception\\authenticationcredentialsnotfoundexception"
app/config/security.yml
security: encoders: fos\userbundle\model\userinterface: sha512 role_hierarchy: role_admin: role_user role_super_admin: role_admin providers: fos_userbundle: id: fos_user.user_provider.username_email firewalls: wsse_secured: pattern: ^/ stateless: true wsse: true anonymous : false main: pattern: ^/ form_login: provider: fos_userbundle csrf_provider: form.csrf_provider logout: true anonymous: true access_control: # tried using - { path: ^/users/$, roles: is_authenticated_anonymously, methods: [post] } - { path: ^/login$, role: is_authenticated_anonymously } - { path: ^/register, role: is_authenticated_anonymously } - { path: ^/resetting, role: is_authenticated_anonymously } - { path: ^/admin/, role: role_admin }
wsseprovider
class wsseprovider implements authenticationproviderinterface { private $userprovider; private $cachedir; public function __construct(userproviderinterface $userprovider, $cachedir) { $this->userprovider = $userprovider; $this->cachedir = $cachedir; } public function authenticate(tokeninterface $token){ $user = $this->userprovider->loaduserbyusername($token->getusername()); if(!$user){ throw new authenticationexception("bad credentials... did forgot username ?"); } if ($user && $this->validatedigest($token->digest, $token->nonce, $token->created, $user->getpassword())) { $authenticatedtoken = new wsseusertoken($user->getroles()); $authenticatedtoken->setuser($user); return $authenticatedtoken; } } protected function validatedigest($digest, $nonce, $created, $secret){ // check created time not in future if (strtotime($created) > time()) { throw new authenticationexception("back future..."); } // expire timestamp after 5 minutes if (time() - strtotime($created) > 300) { throw new authenticationexception("too late timestamp... watch watch."); } // validate nonce unique within 5 minutes if (file_exists($this->cachedir.'/'.$nonce) && file_get_contents($this->cachedir.'/'.$nonce) + 300 > time()) { throw new nonceexpiredexception('previously used nonce detected'); } // if cache directory not exist create if (!is_dir($this->cachedir)) { mkdir($this->cachedir, 0777, true); } file_put_contents($this->cachedir.'/'.$nonce, time()); // validate secret $expected = base64_encode(sha1(base64_decode($nonce).$created.$secret, true)); if($digest !== $expected){ throw new authenticationexception("bad credentials ! digest not expected."); } return true; } public function supports(tokeninterface $token){ return $token instanceof wsseusertoken; } }
wsseusertoken
class wsseusertoken extends abstracttoken { public $created; public $digest; public $nonce; public function __construct(array $roles = array()) { parent::__construct($roles); $this->setauthenticated(count($roles) > 0); } public function getcredentials() { return ''; } }
wsselistener
class wsselistener implements listenerinterface { protected $securitycontext; protected $authenticationmanager; protected $logger; public function __construct(securitycontextinterface $securitycontext, authenticationmanagerinterface $authenticationmanager ) { $this->securitycontext = $securitycontext; $this->authenticationmanager = $authenticationmanager; } public function handle(getresponseevent $event) { $request = $event->getrequest(); $wsseregex = '/usernametoken username="([^"]+)", passworddigest="([^"]+)", nonce="([^"]+)", created="([^"]+)"/'; if (!$request->headers->has('x-wsse') || 1 !== preg_match($wsseregex, $request->headers->get('x-wsse'), $matches) ) { return; } $token = new wsseusertoken(); $token->setuser($matches[1]); $token->digest = $matches[2]; $token->nonce = $matches[3]; $token->created = $matches[4]; try { $authtoken = $this->authenticationmanager->authenticate($token); $this->securitycontext->settoken($authtoken); return; } catch (authenticationexception $failed) { $failedmessage = 'wsse login failed '.$token->getusername().'. why ? '.$failed->getmessage(); // deny authentication '403 forbidden' http response $response = new response(); $response->setstatuscode(403); $response->setcontent($failedmessage); $event->setresponse($response); return; } // default deny authorization $response = new response(); $response->setstatuscode(403); $event->setresponse($response); } }
any appreciated killing me...
Comments
Post a Comment