Skip to content

Commit b46829b

Browse files
authored
Merge pull request #1188 from laravel/auth-token
[8.x] Implement auth token for access requests
2 parents e560aa8 + bf6b57d commit b46829b

9 files changed

+65
-0
lines changed

resources/views/authorize.blade.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969

7070
<input type="hidden" name="state" value="{{ $request->state }}">
7171
<input type="hidden" name="client_id" value="{{ $client->id }}">
72+
<input type="hidden" name="auth_token" value="{{ $authToken }}">
7273
<button type="submit" class="btn btn-success btn-approve">Authorize</button>
7374
</form>
7475

@@ -79,6 +80,7 @@
7980

8081
<input type="hidden" name="state" value="{{ $request->state }}">
8182
<input type="hidden" name="client_id" value="{{ $client->id }}">
83+
<input type="hidden" name="auth_token" value="{{ $authToken }}">
8284
<button class="btn btn-danger">Cancel</button>
8385
</form>
8486
</div>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace Laravel\Passport\Exceptions;
4+
5+
use Illuminate\Auth\Access\AuthorizationException;
6+
7+
class InvalidAuthTokenException extends AuthorizationException
8+
{
9+
/**
10+
* Create a new InvalidAuthTokenException for different auth tokens.
11+
*
12+
* @return static
13+
*/
14+
public static function different()
15+
{
16+
return new static('The provided auth token for the request is different from the session auth token.');
17+
}
18+
}

src/Http/Controllers/ApproveAuthorizationController.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ public function __construct(AuthorizationServer $server)
3636
*/
3737
public function approve(Request $request)
3838
{
39+
$this->assertValidAuthToken($request);
40+
3941
$authRequest = $this->getAuthRequestFromSession($request);
4042

4143
return $this->convertResponse(

src/Http/Controllers/AuthorizationController.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Illuminate\Contracts\Routing\ResponseFactory;
66
use Illuminate\Http\Request;
7+
use Illuminate\Support\Str;
78
use Laminas\Diactoros\Response as Psr7Response;
89
use Laravel\Passport\Bridge\User;
910
use Laravel\Passport\ClientRepository;
@@ -73,13 +74,15 @@ public function authorize(ServerRequestInterface $psrRequest,
7374
return $this->approveRequest($authRequest, $user);
7475
}
7576

77+
$request->session()->put('authToken', $authToken = Str::random());
7678
$request->session()->put('authRequest', $authRequest);
7779

7880
return $this->response->view('passport::authorize', [
7981
'client' => $client,
8082
'user' => $user,
8183
'scopes' => $scopes,
8284
'request' => $request,
85+
'authToken' => $authToken,
8386
]);
8487
}
8588

src/Http/Controllers/DenyAuthorizationController.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ public function __construct(ResponseFactory $response)
3636
*/
3737
public function deny(Request $request)
3838
{
39+
$this->assertValidAuthToken($request);
40+
3941
$authRequest = $this->getAuthRequestFromSession($request);
4042

4143
$clientUris = Arr::wrap($authRequest->getClient()->getRedirectUri());

src/Http/Controllers/RetrievesAuthRequestFromSession.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,25 @@
55
use Exception;
66
use Illuminate\Http\Request;
77
use Laravel\Passport\Bridge\User;
8+
use Laravel\Passport\Exceptions\InvalidAuthTokenException;
89

910
trait RetrievesAuthRequestFromSession
1011
{
12+
/**
13+
* Make sure the auth token matches the one in the session.
14+
*
15+
* @param \Illuminate\Http\Request $request
16+
* @return void
17+
*
18+
* @throws \Laravel\Passport\Exceptions\InvalidAuthTokenException
19+
*/
20+
protected function assertValidAuthToken(Request $request)
21+
{
22+
if ($request->has('auth_token') && $request->session()->get('authToken') !== $request->get('auth_token')) {
23+
throw InvalidAuthTokenException::different();
24+
}
25+
}
26+
1127
/**
1228
* Get the authorization request from the session.
1329
*

tests/ApproveAuthorizationControllerTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,17 @@ public function test_complete_authorization_request()
2626

2727
$request = m::mock(Request::class);
2828
$request->shouldReceive('session')->andReturn($session = m::mock());
29+
$request->shouldReceive('has')->with('auth_token')->andReturn(true);
30+
$request->shouldReceive('get')->with('auth_token')->andReturn('foo');
31+
32+
$session->shouldReceive('get')->once()->with('authToken')->andReturn('foo');
2933
$session->shouldReceive('get')
3034
->once()
3135
->with('authRequest')
3236
->andReturn($authRequest = m::mock(AuthorizationRequest::class));
37+
3338
$request->shouldReceive('user')->andReturn(new ApproveAuthorizationControllerFakeUser);
39+
3440
$authRequest->shouldReceive('getClient->getIdentifier')->andReturn(1);
3541
$authRequest->shouldReceive('getUser->getIdentifier')->andReturn(2);
3642
$authRequest->shouldReceive('setUser')->once();

tests/AuthorizationControllerTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public function test_authorization_view_is_presented()
4343

4444
$request = m::mock(Request::class);
4545
$request->shouldReceive('session')->andReturn($session = m::mock());
46+
$session->shouldReceive('put')->withSomeOfArgs('authToken');
4647
$session->shouldReceive('put')->with('authRequest', $authRequest);
4748
$request->shouldReceive('user')->andReturn($user = m::mock());
4849

tests/DenyAuthorizationControllerTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ public function test_authorization_can_be_denied()
2727
$request->shouldReceive('session')->andReturn($session = m::mock());
2828
$request->shouldReceive('user')->andReturn(new DenyAuthorizationControllerFakeUser);
2929
$request->shouldReceive('input')->with('state')->andReturn('state');
30+
$request->shouldReceive('has')->with('auth_token')->andReturn(true);
31+
$request->shouldReceive('get')->with('auth_token')->andReturn('foo');
3032

33+
$session->shouldReceive('get')->once()->with('authToken')->andReturn('foo');
3134
$session->shouldReceive('get')->once()->with('authRequest')->andReturn($authRequest = m::mock(
3235
AuthorizationRequest::class
3336
));
@@ -56,6 +59,8 @@ public function test_authorization_can_be_denied_with_multiple_redirect_uris()
5659
$request->shouldReceive('session')->andReturn($session = m::mock());
5760
$request->shouldReceive('user')->andReturn(new DenyAuthorizationControllerFakeUser);
5861
$request->shouldReceive('input')->with('state')->andReturn('state');
62+
$request->shouldReceive('has')->with('auth_token')->andReturn(true);
63+
$request->shouldReceive('get')->with('auth_token')->andReturn('foo');
5964

6065
$session->shouldReceive('get')->once()->with('authRequest')->andReturn($authRequest = m::mock(
6166
AuthorizationRequest::class
@@ -67,6 +72,7 @@ public function test_authorization_can_be_denied_with_multiple_redirect_uris()
6772
$authRequest->shouldReceive('getRedirectUri')->andReturn('http://localhost');
6873
$authRequest->shouldReceive('getClient->getRedirectUri')->andReturn(['http://localhost.localdomain', 'http://localhost']);
6974

75+
$session->shouldReceive('get')->once()->with('authToken')->andReturn('foo');
7076
$response->shouldReceive('redirectTo')->once()->andReturnUsing(function ($url) {
7177
return $url;
7278
});
@@ -85,7 +91,10 @@ public function test_authorization_can_be_denied_implicit()
8591
$request->shouldReceive('session')->andReturn($session = m::mock());
8692
$request->shouldReceive('user')->andReturn(new DenyAuthorizationControllerFakeUser);
8793
$request->shouldReceive('input')->with('state')->andReturn('state');
94+
$request->shouldReceive('has')->with('auth_token')->andReturn(true);
95+
$request->shouldReceive('get')->with('auth_token')->andReturn('foo');
8896

97+
$session->shouldReceive('get')->once()->with('authToken')->andReturn('foo');
8998
$session->shouldReceive('get')->once()->with('authRequest')->andReturn($authRequest = m::mock(
9099
AuthorizationRequest::class
91100
));
@@ -114,7 +123,10 @@ public function test_authorization_can_be_denied_with_existing_query_string()
114123
$request->shouldReceive('session')->andReturn($session = m::mock());
115124
$request->shouldReceive('user')->andReturn(new DenyAuthorizationControllerFakeUser);
116125
$request->shouldReceive('input')->with('state')->andReturn('state');
126+
$request->shouldReceive('has')->with('auth_token')->andReturn(true);
127+
$request->shouldReceive('get')->with('auth_token')->andReturn('foo');
117128

129+
$session->shouldReceive('get')->once()->with('authToken')->andReturn('foo');
118130
$session->shouldReceive('get')->once()->with('authRequest')->andReturn($authRequest = m::mock(
119131
AuthorizationRequest::class
120132
));
@@ -146,7 +158,10 @@ public function test_auth_request_should_exist()
146158
$request->shouldReceive('session')->andReturn($session = m::mock());
147159
$request->shouldReceive('user')->never();
148160
$request->shouldReceive('input')->never();
161+
$request->shouldReceive('has')->with('auth_token')->andReturn(true);
162+
$request->shouldReceive('get')->with('auth_token')->andReturn('foo');
149163

164+
$session->shouldReceive('get')->once()->with('authToken')->andReturn('foo');
150165
$session->shouldReceive('get')->once()->with('authRequest')->andReturnNull();
151166

152167
$response->shouldReceive('redirectTo')->never();

0 commit comments

Comments
 (0)