Skip to content

Commit b7ba284

Browse files
author
Jonatan Frank
committed
Oauth2 Implementation
1 parent 89ced2c commit b7ba284

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1885
-76
lines changed

app/AppKernel.php

+3
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@ public function registerBundles()
1919
new AppBundle\AppBundle(),
2020
new Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle(),
2121
new Nelmio\CorsBundle\NelmioCorsBundle(),
22+
new FOS\OAuthServerBundle\FOSOAuthServerBundle(),
23+
new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle()
2224
);
2325

2426
if (in_array($this->getEnvironment(), array('dev', 'test'))) {
27+
// $bundles[] = new Acme\DemoBundle\AcmeDemoBundle();
2528
$bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle();
2629
$bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
2730
$bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle();

app/DoctrineMigrations/Version20150410170543.php

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public function up(Schema $schema)
3030
$listsCategories->addColumn('category_id', 'integer');
3131
$listsCategories->addIndex(array('productlist_id'));
3232
$listsCategories->addIndex(array('category_id'));
33+
$listsCategories->setPrimaryKey(array('productlist_id', 'category_id'));
3334
$product = $schema->createTable('product');
3435
$product->addColumn('id', 'integer', array('autoincrement' => true));
3536
$product->addColumn('category_id', 'integer');
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
namespace Application\Migrations;
4+
5+
use Doctrine\DBAL\Migrations\AbstractMigration;
6+
use Doctrine\DBAL\Schema\Schema;
7+
8+
/**
9+
* Auto-generated Migration: Please modify to your needs!
10+
*/
11+
class Version20150413165736 extends AbstractMigration
12+
{
13+
/**
14+
* @param Schema $schema
15+
*/
16+
public function up(Schema $schema)
17+
{
18+
$client = $schema->createTable('client');
19+
$client->addColumn('id', 'integer', array('autoincrement' => true));
20+
$client->addColumn('random_id', 'string');
21+
$client->addColumn('redirect_uris', 'array');
22+
$client->addColumn('secret', 'string');
23+
$client->addColumn('allowed_grant_types', 'array');
24+
$client->setPrimaryKey(array('id'));
25+
$users = $schema->createTable('users');
26+
$users->addColumn('id', 'integer', array('autoincrement' => true));
27+
$users->addColumn('username', 'string', array('length' => 25));
28+
$users->addColumn('email', 'string', array('length' => 25));
29+
$users->addColumn('salt', 'string', array('length' => 32));
30+
$users->addColumn('password', 'string', array('length' => 40));
31+
$users->addColumn('is_active', 'boolean');
32+
$users->addUniqueIndex(array('username'));
33+
$users->addUniqueIndex(array('email'));
34+
$users->setPrimaryKey(array('id'));
35+
$authCode = $schema->createTable('auth_code');
36+
$authCode->addColumn('id', 'integer', array('autoincrement' => true));
37+
$authCode->addColumn('client_id', 'integer');
38+
$authCode->addColumn('user_id', 'integer');
39+
$authCode->addColumn('token', 'string');
40+
$authCode->addColumn('redirect_uri', 'text');
41+
$authCode->addColumn('expires_at', 'integer');
42+
$authCode->addColumn('scope', 'string');
43+
$authCode->addUniqueIndex(array('token'));
44+
$authCode->addIndex(array('client_id'));
45+
$authCode->addIndex(array('user_id'));
46+
$authCode->setPrimaryKey(array('id'));
47+
$accessToken = $schema->createTable('access_token');
48+
$accessToken->addColumn('id', 'integer', array('autoincrement' => true));
49+
$accessToken->addColumn('client_id', 'integer');
50+
$accessToken->addColumn('token', 'string');
51+
$accessToken->addColumn('expires_at', 'integer');
52+
$accessToken->addColumn('scope', 'string');
53+
$accessToken->addUniqueIndex(array('token'));
54+
$accessToken->addIndex(array('client_id'));
55+
$accessToken->setPrimaryKey(array('id'));
56+
$refreshToken = $schema->createTable('refresh_token');
57+
$refreshToken->addColumn('id', 'integer', array('autoincrement' => true));
58+
$refreshToken->addColumn('client_id', 'integer');
59+
$refreshToken->addIndex(array('client_id'));
60+
$refreshToken->addColumn('token', 'string');
61+
$refreshToken->addColumn('expires_at', 'integer');
62+
$refreshToken->addColumn('scope', 'string');
63+
$refreshToken->addUniqueIndex(array('token'));
64+
$refreshToken->setPrimaryKey(array('id'));
65+
$authCode->addForeignKeyConstraint($client, array('client_id'), array('id'));
66+
$authCode->addForeignKeyConstraint($users, array('user_id'), array('id'));
67+
$accessToken->addForeignKeyConstraint($client, array('client_id'), array('id'));
68+
$accessToken->addForeignKeyConstraint($users, array('user_id'), array('id'));
69+
$refreshToken->addForeignKeyConstraint($client, array('client_id'), array('id'));
70+
$refreshToken->addForeignKeyConstraint($users, array('user_id'), array('id'));
71+
}
72+
73+
/**
74+
* @param Schema $schema
75+
*/
76+
public function down(Schema $schema)
77+
{
78+
$schema->dropTable('auth_code');
79+
$schema->dropTable('access_token');
80+
$schema->dropTable('refresh_token');
81+
$schema->dropTable('client');
82+
$schema->dropTable('users');
83+
}
84+
}

app/Resources/views/login.html.twig

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{% extends "base.html.twig" %}
2+
{% block body %}
3+
<div class="form">
4+
<form action="" method="post">
5+
<h2>OAuth Authorization</h2>
6+
{% if(error) %}
7+
<div class='form_error' style="color: red"></div>
8+
{% endif %}
9+
<div class="form_item">
10+
<div class="form_label"><label for="username">Username</label>:</div>
11+
<div class="form_widget"><input type="text" id="username" name="_username" /></div>
12+
</div>
13+
<div class="form_item">
14+
<div class="form_label"><label for="password">Password</label>:</div>
15+
<div class="form_widget"><input type="password" id="password" name="_password" /></div>
16+
</div>
17+
<div class="form_button">
18+
<input type="submit" id="_submit" name="_submit" value="Log In" />
19+
</div>
20+
</form>
21+
</div>
22+
{% endblock %}

app/config/config.yml

+13-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ imports:
55

66
framework:
77
#esi: ~
8-
#translator: { fallbacks: ["%locale%"] }
8+
translator: { fallbacks: ["%locale%"] }
99
secret: "%secret%"
1010
router:
1111
resource: "%kernel.root_dir%/config/routing.yml"
@@ -88,4 +88,15 @@ nelmio_cors:
8888
allow_origin: ['*']
8989
allow_headers: ['*']
9090
allow_methods: ['POST', 'GET', 'PUT', 'DELETE']
91-
max_age: 3600
91+
max_age: 3600
92+
93+
fos_oauth_server:
94+
db_driver: orm
95+
client_class: AppBundle\Entity\Client
96+
access_token_class: AppBundle\Entity\AccessToken
97+
refresh_token_class: AppBundle\Entity\RefreshToken
98+
auth_code_class: AppBundle\Entity\AuthCode
99+
service:
100+
user_provider: platform.user.provider
101+
options:
102+
supported_scopes: user

app/config/routing.yml

+14
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
11
app:
22
resource: "@AppBundle/Controller/"
33
type: annotation
4+
5+
fos_oauth_server_token:
6+
resource: "@FOSOAuthServerBundle/Resources/config/routing/token.xml"
7+
8+
fos_oauth_server_authorize:
9+
resource: "@FOSOAuthServerBundle/Resources/config/routing/authorize.xml"
10+
11+
acme_oauth_server_auth_login:
12+
pattern: /oauth/v2/auth_login
13+
defaults: { _controller: AppBundle:Security:login }
14+
15+
acme_oauth_server_auth_login_check:
16+
pattern: /oauth/v2/auth_login_check
17+
defaults: { _controller: AppBundle:Security:loginCheck }

app/config/routing_dev.yml

+4
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,7 @@ _errors:
1616

1717
_main:
1818
resource: routing.yml
19+
20+
## AcmeDemoBundle routes (to be removed)
21+
#_acme_demo:
22+
# resource: "@AcmeDemoBundle/Resources/config/routing.yml"

app/config/security.yml

+30-30
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,52 @@
1-
# you can read more about security in the related section of the documentation
2-
# http://symfony.com/doc/current/book/security.html
1+
32
security:
4-
# http://symfony.com/doc/current/book/security.html#encoding-the-user-s-password
53
encoders:
6-
Symfony\Component\Security\Core\User\User: plaintext
4+
AppBundle\Entity\User:
5+
algorithm: sha1
6+
encode_as_base64: false
7+
iterations: 1
78

8-
# http://symfony.com/doc/current/book/security.html#hierarchical-roles
99
role_hierarchy:
1010
ROLE_ADMIN: ROLE_USER
11-
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
11+
ROLE_SUPER_ADMIN: ROLE_ADMIN
1212

13-
# http://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers
1413
providers:
15-
in_memory:
16-
memory:
17-
users:
18-
user: { password: userpass, roles: [ 'ROLE_USER' ] }
19-
admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] }
14+
user_provider:
15+
id: platform.user.provider
2016

21-
# the main part of the security, where you can set up firewalls
22-
# for specific sections of your app
2317
firewalls:
24-
# disables authentication for assets and the profiler, adapt it according to your needs
2518
dev:
2619
pattern: ^/(_(profiler|wdt)|css|images|js)/
2720
security: false
28-
# the login page has to be accessible for everybody
29-
demo_login:
30-
pattern: ^/demo/secured/login$
21+
22+
login:
23+
pattern: ^/oauth/v2/auth_login$
3124
security: false
25+
oauth_token:
26+
pattern: ^/oauth/v2/token
27+
security: false
3228

33-
# secures part of the application
34-
demo_secured_area:
29+
secured_area:
3530
pattern: ^/demo/secured/
36-
# it's important to notice that in this case _demo_security_check and _demo_login
37-
# are route names and that they are specified in the AcmeDemoBundle
3831
form_login:
39-
check_path: _demo_security_check
32+
provider: user_provider
33+
check_path: _security_check
4034
login_path: _demo_login
4135
logout:
4236
path: _demo_logout
4337
target: _demo
44-
#anonymous: ~
45-
#http_basic:
46-
# realm: "Secured Demo Area"
38+
oauth_authorize:
39+
pattern: ^/oauth/v2/auth
40+
form_login:
41+
provider: user_provider
42+
check_path: _security_check
43+
login_path: _demo_login
44+
anonymous: true
45+
api:
46+
pattern: ^/api
47+
fos_oauth: true
48+
stateless: true
4749

48-
# with these settings you can restrict or allow access for different parts
49-
# of your application based on roles, ip, host or methods
50-
# http://symfony.com/doc/current/cookbook/security/access_control.html
5150
access_control:
52-
#- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
51+
- { path: ^/api, roles: [ IS_AUTHENTICATED_FULLY ] }
52+
- { path: ^/demo/secured/hello/admin/, roles: ROLE_ADMIN }

app/config/services.yml

+18-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
# Learn more about services, parameters and containers at
22
# http://symfony.com/doc/current/book/service_container.html
33
parameters:
4-
# parameter_name: value
4+
# platform.entity.user.class: Acme\DemoBundle\Entity\User
5+
# platform.user.provider.class: Acme\DemoBundle\Provider\UserProvider
56

67
services:
7-
# service_name:
8-
# class: AppBundle\Directory\ClassName
9-
# arguments: ["@another_service_name", "plain_value", "%parameter_name%"]
8+
platform.user.manager:
9+
class: Doctrine\ORM\EnityManager
10+
factory: ["@doctrine", getManagerForClass]
11+
arguments:
12+
- AppBundle\Entity\User
13+
platform.user.repository:
14+
class: AppBundle\Entity\UserRepository
15+
factory: ["@platform.user.manager", getRepository]
16+
arguments:
17+
- AppBundle\Entity\User
18+
platform.user.provider:
19+
class: AppBundle\Provider\UserProvider
20+
arguments:
21+
- "@platform.user.repository"
22+
23+

composer.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
"incenteev/composer-parameter-handler": "~2.0",
2424
"doctrine/migrations": "1.0.*@dev",
2525
"doctrine/doctrine-migrations-bundle": "2.1.*@dev",
26-
"nelmio/cors-bundle": "~1.4"
26+
"doctrine/doctrine-fixtures-bundle": "2.2.*",
27+
"nelmio/cors-bundle": "~1.4",
28+
"friendsofsymfony/oauth-server-bundle": "dev-master"
2729
},
2830
"require-dev": {
2931
"sensio/generator-bundle": "~2.3"

0 commit comments

Comments
 (0)