Giter Site home page Giter Site logo

oauth2-server-bundle's Introduction

OAuth2 Server Bundle

OAuth2 Server Bundle for Symfony 2, built on the oauth2-server-php library.

Build Status

Getting Started

See the Complete Documentation for information regarding the OAuth2.0 protocol and the PHP library used by this bundle to implement it.

For documentation specific to this bundle, continue reading below.

Bundle Overview

The following grant types are supported out the box:

  • Client Credentials
  • Authorization Code
  • Refresh Token
  • User Credentials (see below)

You can make token requests to the /token path via POST.

You can restrict the grant types available per client in the database, use a Compiler Pass or in your own TokenController you could do something like:

public function tokenAction()
{
    $server = $this->get('oauth2.server');

    // Override default grant types to authorization code only
    $server->addGrantType($this->get('oauth2.grant_type.authorization_code'));

    return $server->handleTokenRequest($this->get('oauth2.request'), $this->get('oauth2.response'));
}

Installation

Step 1: Add package to Composer

Use composer to add the requirement and download it by running the command:

$ php composer.phar require bshaffer/oauth2-server-bundle

Composer will update your composer.json and install the bundle to your project's vendor/bshaffer directory.

Step 2: Enable the bundle

Enable the bundle in the kernel:

<?php
// app/AppKernel.php

public function registerBundles()
{
    $bundles = array(
        // ...
        new OAuth2\ServerBundle\OAuth2ServerBundle(),
    );
}

Step 3: Install database

You'll need to update your schema to setup the Entities provided by this module.

$ php app/console doctrine:schema:update --force

Step 4: Add routes

You'll need to add the following to your routing.yml

# app/config/routing.yml

oauth2_server:
    resource: "@OAuth2ServerBundle/Controller/"
    type:     annotation
    prefix:   /

Step 5: Create a scope

You'll need to setup a scope before you can create a client, use this command. The description you give here will appear on the Authorization page.

$ php app/console OAuth2:CreateScope scope (description)

Step 6: Create a client

Use this console command to create a new client:

$ php app/console OAuth2:CreateClient client_id redirect_uri (grant_types) (scope)

Optional Configuration

You can override any of the built-in components in your own bundle by adding new parameters in your config.yml:

# app/config/config.yml

parameters:
    oauth2.storage.client_credentials.class: Amce\OAuth2ServerBundle\Storage\ClientCredentials

Where Amce\OAuth2ServerBundle\Storage\ClientCredentials is your own implementation of the ClientCredentials interface.

If you provide your own storage managers then you'll be able to hook everything up to your own custom Entities.

User Credentials (Resource Owner Password)

To make it easy to plug-in your own User Provider we've conformed to the UserInterface, UserProviderInterface & EncoderFactoryInterface.

Therefore to make proper use of the user credentials grant type you'll need to modify your config.yml with the relevant classes.

# app/config/config.yml

parameters:
    oauth2.user_provider.class: Amce\OAuth2ServerBundle\User\OAuth2UserProvider

If you want to take advantage of scope restriction on a per user basis your User entity will need to implement the OAuth2\ServerBundle\OAuth2UserInterface or OAuth2\ServerBundle\AdvancedOAuth2UserInterface.

Out of the box we do provide a basic user provider and entity for you to use. Setup your security.yml to use it:

# app/config/security.yml

security:
    encoders:
        OAuth2\ServerBundle\Entity\User:
            algorithm:          sha512
            encode_as_base64:   true
            iterations:         5000

    providers:
        oauth2:
            id: oauth2.user_provider

You'll need some users first though! Use the console command to create a new user:

$ php app/console OAuth2:CreateUser username password

Configuring Grant Types

You'll need to use a Compiler Pass to configure settings for a grant type. For example say we want our refresh tokens to always get renewed:

// Amce/OAuth2ServerBundle/AmceOAuth2ServerBundle.php

namespace Amce\OAuth2ServerBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Amce\OAuth2ServerBundle\DependencyInjection\Compiler\OAuth2CompilerPass;

class AmceOAuth2ServerBundle extends Bundle
{
    public function build(ContainerBuilder $container)
    {
        parent::build($container);

        $container->addCompilerPass(new OAuth2CompilerPass());
    }
}
// Amce/OAuth2ServerBundle/DependencyInjection\Compiler\OAuth2CompilerPass.php

namespace Amce\OAuth2ServerBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Reference;

class OAuth2CompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        // Override Refresh Token Grant Type Settings
        $serviceId = 'oauth2.grant_type.refresh_token';
        if ($container->hasDefinition($serviceId)) {
            $definition = $container->getDefinition($serviceId);
            $definition->replaceArgument(1, array(
                'always_issue_new_refresh_token' => TRUE
            ));
        }
    }
}

oauth2-server-bundle's People

Contributors

bshaffer avatar elhachmi avatar jdelaune avatar jkobus avatar rawi01 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

oauth2-server-bundle's Issues

Authorization Code & Login Forms

I know this bundle is early in development (only v0.2), but I was wondering what the plans were for adding a way to hook into an existing authentication system (like FOSUserBundle), so we could have the authorization code flow like Google, Facebook, Github, where you can login and manage your authorizations and such.

I might be missing this if it's already in the bundle, I'm pretty new to Symfony. If I am could you just point out to me how I might implement a login form with this?

user_id is not passed in ClientCredentials

From what I see in GrantType/ClientCredentials.php in method getUserId we request $this->clientData['user_id'].
Going to Storage/ClientCredentials.php it seems this storage do not return user_id. Also, in oauth_client table there is no column user_id.

Then, if we have ability to create custom UserProvider, it means that this provider should be used when retrieving user.

Question is - it is intentional, or it might be implemented or what is the appropriate solution in this case?

"The grant type was not specified in the request"

I have the following code to test against a local instance of this oauth2-server-bundle that I included in a symfony demo app for test purposes.

I am testing the token endpoint.

When I test with the code below I get the error message:

"The grant type was not specified in the request"

Can anyone tell me why?

When I debug I see that the $_REQUEST does contain all parameters but the

$this->get('oauth2.request') does not contain any of the parameters.

When I use a straight curl command from the terminal as demonstrated in the documentation

curl -u testclient:testpass http://localhost/token.php -d 'grant_type=authorization_code&code=YOUR_CODE'

I don't have any problems. I get back the expected results.

    $username='oauthopenidserver';
    $password='rfl703uk0qsgwg0gs840w0c8884s0w4';
    $url = 'http://oauthopenidserver.com:8080/token';
    $fields = array(
        'code' => $auth_code,
        'grant_type' => 'authorization_code',
        'redirect_uri' => 'http://localhost:8000/en/sso/login_oidc',
        'scope' => 'openid',
    );

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30); //timeout after 30 seconds
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
    curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
    curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
    curl_setopt($ch, CURLOPT_POST, true);
    $status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);   //get status code
    $response=curl_exec ($ch);
    curl_close ($ch);

Undefined method errors after PR #42

I'm getting the following error on the authorization endpoint after updating to the latest commit containing PR #42:

Symfony\Component\Debug\Exception\UndefinedMethodException: Attempted to call an undefined method named "createFromRequestStack" of class "OAuth2\HttpFoundationBridge\Request".
Did you mean to call "createFromRequest"?

Validate token

I am looking to use oauth2 to restrict access to an API that I have created using Restler. Restler is supposed to use your server library. Based upon using oauth2-server-bundle or Restler, how do I validate the token and then redirect to the API?

Make all OAuth2-services public

Make all defines services in oauth2-server-bundle/Resources/config/services.xml public so Symfony 3 & Symfony 4 can use them via $controller->get(). Per default all defined services are now private.

services.txt

Documentation improvements and bundle configuration

Hi @bshaffer,

Thanks for this great work, as far as I could test it seems neat and flexible.

I'm currently trying to create my own OAuth server with your bundle and I've some problems of implementation.

The context is a bit unusual: my project don't store users password. It uses a external authentication system which provide only the user login. Thus I can't create a UserProvider as I don't have any passwords in my database.

What would be the best way to create a three legged authentication code oauth server without user provider ? It seems possible, but after some tests I didn't find anything conclusive.

And by the way, I know how hard it is to write a good documentation when you are the developper, as you can't understand the users problems. If you want, I can explain to you what I don't get about the bundle to improve doc.

PS : a reference for configuration, grant types, storage implementations etc. could be really useful!

function checkScope receives array of string as the second parameter but it expects a string

Hi @bshaffer,

When executing the following curl command to test the token endpoint:

curl -u testuser:testpass https://someIP/Symfony-OAuth-Server/web/app_dev.php/token -k -d 'grant_type=client_credentials&scope=photo_engine'

the following error is given:

in /var/www/Symfony-OAuth-Server/vendor/bshaffer/oauth2-server-php/src/OAuth2/Scope.php line 49

at Symfony\Component\Debug\ErrorHandler-&gt;handle(&#039;2&#039;, &#039;trim() expects parameter 1 to be string, array given&#039;, &#039;/var/www/Symfony-OAuth-Server/vendor/bshaffer/oauth2-server-php/src/OAuth2/Scope.php&#039;, &#039;49&#039;, array(&#039;required_scope&#039; =&gt; array(&#039;photo_engine&#039;), &#039;available_scope&#039; =&gt; array(&#039;xyz&#039;, &#039;photo_engine&#039;)))
    in  line

at trim(array(&#039;xyz&#039;, &#039;photo_engine&#039;))
    in /var/www/Symfony-OAuth-Server/vendor/bshaffer/oauth2-server-php/src/OAuth2/Scope.php line 49

at OAuth2\Scope-&gt;checkScope(&#039;photo_engine&#039;, array(&#039;xyz&#039;, &#039;photo_engine&#039;))
    in /var/www/Symfony-OAuth-Server/vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/TokenController.php line 173

at OAuth2\Controller\TokenController-&gt;grantAccessToken(object(Request), object(Response))
    in /var/www/Symfony-OAuth-Server/vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/TokenController.php line 49

at OAuth2\Controller\TokenController-&gt;handleTokenRequest(object(Request), object(Response))
    in /var/www/Symfony-OAuth-Server/vendor/bshaffer/oauth2-server-php/src/OAuth2/Server.php line 256

at OAuth2\Server-&gt;handleTokenRequest(object(Request), object(Response))
    in /var/www/Symfony-OAuth-Server/vendor/bshaffer/oauth2-server-bundle/OAuth2/ServerBundle/Controller/TokenController.php line 31

What happens is that the function checkScope gets an array of available scopes as the second parameter and tries to trim it. Either the function checkScope should get string as the second parameter or it should not be trimmed because array is already provided.

This kind of behaviour comes out of the box.

http_basic included in README

I suggest to include that http_basic in a firewall configuration in app/config/security.yml shouldn't be setted as true.

User credentials issue

Hello,

I followed the readme instructions and added this to my config.yml :

oauth2.user_provider.class: Amce\OAuth2ServerBundle\User\OAuth2UserProvider

But it doesn't work, so i noticed it should be Acme instead of Amce, but same thing i can't get it to work, i get this error :

PHP Fatal error: Class 'Acme\OAuth2ServerBundle\User\OAuth2UserProvider' not found in /home/myuser/oauthserver/var/cache/dev/appDevDebugProjectContainer.php on line 2239

NOTICE: Deleted Master Branch

Yes, I deleted the master branch. Any composer references to dev-master will no longer work. Please update your code to use the latest tag (0.4)

ClientCredentials misses two interface methods

OAuth2\ServerBundle\Storage\ClientCredentials misses two interface methods. This causes a fatal error:

Fatal error: Class OAuth2\ServerBundle\Storage\ClientCredentials contains 2 abstract methods and must therefore be declared abstract or implement the remaining methods (OAuth2\Storage\ClientCredentialsInterface::isPublicClient, OAuth2\Storage\ClientInterface::getClientScope) in my/project/vendor/bshaffer/oauth2-server-bundle/OAuth2/ServerBundle/Storage/ClientCredentials.php on line 116

Introduce mapped-superclass

I think it could be really nice to change entities to mapped superclass to be able to inherit those class when needed. A little bit like FOSUserBundle does.

At the moment, I would like to add informations in the Client and the User entities but as a limitation with Doctrine and Entities, I can't do that without changing the server code. But I guess, it could be useful also with other entities.

OpenID Connect support

It seems that oauth2-server-php supports OpenID Connect. Does it mean this bundle does it too?

TokenController.php and RouteController.php have the same route annotation

Hi @bshaffer,

When testing the resource endpoint

curl -u testclient:testpass https://serverIP/Symfony-OAuth-Server/web/app_dev.php/resource -k -d 'access_token=YOUR_TOKEN'

the TokenController gets executed instead of the ResourceController.

It is due to the fact that the ResourceController and TokenController have exactly the same route annotation. ResourceController should have the route e.g. @route("/resource", name="_resource") instead of @route("/token", name="_token").

After modifying the route the following error is raised:

CRITICAL - Uncaught PHP Exception ReflectionException: "Class OAuth2\ServerBundle\Controller\Application does not exist" at /var/www/Symfony-OAuth-Server/app/cache/dev/classes.php line 5997

Here is the full stack trace:

in /var/www/Symfony-OAuth-Server/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/EventListener/ParamConverterListener.php line 81

at ReflectionParameter-&gt;getClass()
    in /var/www/Symfony-OAuth-Server/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/EventListener/ParamConverterListener.php line 81

at Sensio\Bundle\FrameworkExtraBundle\EventListener\ParamConverterListener-&gt;autoConfigure(object(ReflectionMethod), object(Request), array())
    in /var/www/Symfony-OAuth-Server/vendor/sensio/framework-extra-bundle/Sensio/Bundle/FrameworkExtraBundle/EventListener/ParamConverterListener.php line 72

at Sensio\Bundle\FrameworkExtraBundle\EventListener\ParamConverterListener-&gt;onKernelController(object(FilterControllerEvent), &#039;kernel.controller&#039;, object(ContainerAwareEventDispatcher))
    in  line

at call_user_func(array(object(ParamConverterListener), &#039;onKernelController&#039;), object(FilterControllerEvent), &#039;kernel.controller&#039;, object(ContainerAwareEventDispatcher))
    in /var/www/Symfony-OAuth-Server/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php line 59

at Symfony\Component\EventDispatcher\Debug\WrappedListener-&gt;__invoke(object(FilterControllerEvent), &#039;kernel.controller&#039;, object(ContainerAwareEventDispatcher))
    in  line

at call_user_func(object(WrappedListener), object(FilterControllerEvent), &#039;kernel.controller&#039;, object(ContainerAwareEventDispatcher))
    in /var/www/Symfony-OAuth-Server/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php line 164

at Symfony\Component\EventDispatcher\EventDispatcher-&gt;doDispatch(array(object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener)), &#039;kernel.controller&#039;, object(FilterControllerEvent))
    in /var/www/Symfony-OAuth-Server/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php line 53

at Symfony\Component\EventDispatcher\EventDispatcher-&gt;dispatch(&#039;kernel.controller&#039;, object(FilterControllerEvent))
    in /var/www/Symfony-OAuth-Server/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php line 167

at Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher-&gt;dispatch(&#039;kernel.controller&#039;, object(FilterControllerEvent))
    in /var/www/Symfony-OAuth-Server/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php line 112

at Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher-&gt;dispatch(&#039;kernel.controller&#039;, object(FilterControllerEvent))
    in /var/www/Symfony-OAuth-Server/app/bootstrap.php.cache line 2971

at Symfony\Component\HttpKernel\HttpKernel-&gt;handleRaw(object(Request), &#039;1&#039;)
    in /var/www/Symfony-OAuth-Server/app/bootstrap.php.cache line 2936

at Symfony\Component\HttpKernel\HttpKernel-&gt;handle(object(Request), &#039;1&#039;, true)
    in /var/www/Symfony-OAuth-Server/app/bootstrap.php.cache line 3085

at Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel-&gt;handle(object(Request), &#039;1&#039;, true)
    in /var/www/Symfony-OAuth-Server/app/bootstrap.php.cache line 2335

at Symfony\Component\HttpKernel\Kernel-&gt;handle(object(Request))
    in /var/www/Symfony-OAuth-Server/web/app_dev.php line 28

composer dependencies error

did exectly what you wrote in you examples.

composer update bshaffer/oauth2-server-bundle
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Installation request for bshaffer/oauth2-server-bundle dev-master -> satisfiable by bshaffer/oauth2-server-bundle[dev-master].
    - bshaffer/oauth2-server-bundle dev-master requires bshaffer/oauth2-server-php dev-master -> no matching package found.

Potential causes:
 - A typo in the package name
 - The package is not available in a stable-enough version according to your minimum-stability setting
   see <https://groups.google.com/d/topic/composer-dev/_g3ASeIFlrc/discussion> for more details.

Read <http://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.

Composer...why no tags?

Problem 1
- Installation request for bshaffer/oauth2-server-bundle dev-master -> satisfiable by bshaffer/oauth2-server-bundle[dev-master].
- bshaffer/oauth2-server-bundle dev-master requires bshaffer/oauth2-server-php dev-master -> no matching package found.

Can't you just create a tag, like you're supposed to do?

Error install via composer

$ php composer.phar update bshaffer/oauth2-server-bundle

Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Installation request for bshaffer/oauth2-server-bundle dev-master -> satisfiable by bshaffer/oauth2-server-bundle[dev-master].
    - bshaffer/oauth2-server-bundle dev-master requires bshaffer/oauth2-server-php dev-develop -> no matching package found.
  Problem 2
    - bshaffer/oauth2-server-bundle dev-master requires bshaffer/oauth2-server-php dev-develop -> no matching package found.
    - symfony/framework-standard-edition 2.4.x-dev requires bshaffer/oauth2-server-bundle dev-master -> satisfiable by bshaffer/oauth2-server-bundle[dev-master].
    - Installation request for symfony/framework-standard-edition 2.4.x-dev -> satisfiable by symfony/framework-standard-edition[2.4.x-dev].

Potential causes:
 - A typo in the package name
 - The package is not available in a stable-enough version according to your minimum-stability setting
   see <https://groups.google.com/d/topic/composer-dev/_g3ASeIFlrc/discussion> for more details.

Read <http://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.

Provide easy means to change entity managers

Allow configuration to switch entity managers.

We use several database connections and manually map our entity managers. This causes problems when we don't want the OAuth entities to exist in the main entity manager.

As a workaround I added a compiler pass which while not the prettiest of solutions but it allows everything to work as intended.


use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

class OAuthCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        $replaceEmServices = [
            'oauth2.user_provider',
            'oauth2.scope_manager',
            'oauth2.storage.client_credentials',
            'oauth2.storage.authorization_code',
            'oauth2.storage.user_credentials',
            'oauth2.storage.access_token',
            'oauth2.storage.refresh_token',
            'oauth2.storage.scope',
            'oauth2.client_manager',
        ];

        //Set this to the service id of your entity manager
        $newEntityManager = 'doctrine.orm.connect_entity_manager';

        foreach ($replaceEmServices as $serviceId) {
            if ($container->hasDefinition($serviceId)) {
                $definition = $container->getDefinition($serviceId);
                $reference  = new Reference($newEntityManager);

                $definition->replaceArgument(0, $reference);
            }
        }
    }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.