How to access Symfony OAuth2 api from main firewall without tokens

FriendsOfSymfony/FOSOAuthServerBundle is a very powerful plugin, however you cannot use API from your main web app without going through the oauth2 authentication process. I searched lot of websites and finally came to a solution by my self.

First of all put all your api controllers inside Acme/DemoBundle/ApiController/ and your twig controllers stays in Acme/DemoBundle/Controller/

We have to import API routes in Acme/DemoBundle/ApiController/ twice with different prefixes.

  • api/some/url
  • web-api/some/url

So that we can use web-api/ urls from within main firewall

app/config/security.yml

security:
    firewalls:
        api:
            pattern:  ^/api
            fos_oauth: true
            stateless: true
        secured_area:
            pattern:  ^/
            form_login:
                login_path: /login
                check_path: /login_check
            logout:
                path:   /logout
                target: /login
            anonymous: false

Unfortunately it is not possible to import routes twice, since route names are unique in the system. However with a little trick we could import routes using a different name prefix.

Acme/DemoBundle/Resources/config/services.yml

services:

    acme.routing_loader:
        class: Acme\DemoBundle\Service\RoutingLoaderService
        tags:
            - { name: routing.loader }

Acme/DemoBundle/Service/RoutingLoaderService.php

<?php
namespace Acme\DemoBundle\Service;

use Symfony\Component\Config\Loader\Loader;
use Symfony\Component\Routing\RouteCollection;

class RoutingLoaderService extends Loader {

    var $typePrefix = 'annotation/';

    public function load($resource, $type = null)
    {
        $routeNamePrefix = substr($type,strlen($this->typePrefix));
        $collection = new RouteCollection();
        $routes = $this->import($resource, 'annotation');
        $routes2 = clone $routes;
        foreach ($routes as $name => $route) {
            $routes2->add($routeNamePrefix.$name,$route);
            $routes2->remove($name);
        }
        $collection->addCollection($routes2);
        return $collection;
    }

    public function supports($resource, $type = null)
    {
        return substr($type,0,strlen($this->typePrefix))===$this->typePrefix;
    }

}

and finally

app/config/routing.yml

AcmeDemoBundle:
    resource: "@AcmeDemoBundle/Controller/"
    type:     annotation
    prefix:   /

AcmeDemoBundle_api:
    resource: "@AcmeDemoBundle/ApiController/"
    type:     annotation/api_
    prefix: /api/

AcmeDemoBundle_web-api:
    resource: "@AcmeDemoBundle/ApiController/"
    type:     annotation/web-api_
    prefix: /web-api/
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories