@@ -24,6 +24,10 @@ public function __construct(HttpKernelInterface $app, array $options = array())
2424
2525 public function handle (Request $ request , $ type = HttpKernelInterface::MASTER_REQUEST , $ catch = true )
2626 {
27+ // The challenge callback is called if a 401 response is detected that
28+ // has a "WWW-Authenticate: Stack" header. This is per the Stack
29+ // Authentication and Authorization proposals. It is passed the existing
30+ // response object.
2731 $ challenge = function (Response $ response ) {
2832 $ parts = ['Basic ' ];
2933 if (isset ($ this ->container ['realm ' ])) {
@@ -35,38 +39,55 @@ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQ
3539 return $ response ;
3640 };
3741
38- $ firewalls = isset ($ this ->container ['firewalls ' ])
39- ? $ this ->container ['firewalls ' ]
40- : [];
41-
42- list ($ isResponse , $ value , $ firewall ) = \Stack \Security \authenticate (
43- $ this ->app ,
44- $ challenge ,
45- $ firewalls ,
46- $ request ,
47- $ type ,
48- $ catch
49- );
50-
51- if ($ isResponse ) {
52- return $ value ;
53- }
54-
55- $ delegate = $ value ;
56-
57- if (false === $ username = $ request ->headers ->get ('PHP_AUTH_USER ' , false )) {
58- return call_user_func ($ delegate );
59- }
42+ // The authenticate callback is called if the request has no Stack
43+ // authentication token but there is an authorization header. It is
44+ // passed an app we should delegate to (assuming we do not return
45+ // beforehand) and a boolean value indicating whether or not anonymous
46+ // requests should be allowed.
47+ $ authenticate = function ($ app , $ anonymous ) use ($ request , $ type , $ catch , $ challenge ) {
48+ if (false === $ username = $ request ->headers ->get ('PHP_AUTH_USER ' , false )) {
49+ if ($ anonymous ) {
50+ // This is not a Basic Auth request but the firewall allows
51+ // anonymous requests so we should wrap the application
52+ // so that we might be able to challenge if authorization
53+ // fails.
54+ return (new WwwAuthenticateStackChallenge ($ app , $ challenge ))
55+ ->handle ($ request , $ type , $ catch );
56+ }
57+
58+ // Anonymous requests are not allowed so we should challenge
59+ // immediately.
60+ return call_user_func ($ challenge , (new Response )->setStatusCode (401 ));
61+ }
6062
61- $ token = $ this ->container ['authenticator ' ]($ username , $ request ->headers ->get ('PHP_AUTH_PW ' ));
63+ $ token = $ this ->container ['authenticator ' ]($ username , $ request ->headers ->get ('PHP_AUTH_PW ' ));
64+
65+ if (null === $ token ) {
66+ if ($ anonymous ) {
67+ // Authentication faild but anonymous requests are allowed
68+ // so we will pass this on. If authorization fails, we have
69+ // wrapped the app in a challenge middleware that will let
70+ // us challenge for basic auth.
71+ return (new WwwAuthenticateStackChallenge ($ app , $ challenge ))
72+ ->handle ($ request , $ type , $ catch );
73+ }
74+
75+ // We should challenge immediately if anonymous requests are not
76+ // allowed.
77+ return call_user_func ($ challenge , (new Response )->setStatusCode (401 ));
78+ }
6279
63- if (null === $ token ) {
64- return \Stack \Security \delegate_missing_authentication ($ firewall , $ delegate , $ challenge );
65- }
80+ $ request ->attributes ->set ('stack.authn.token ' , $ token );
6681
67- $ request ->attributes ->set ('stack.authn.token ' , $ token );
82+ return $ app ->handle ($ request , $ type , $ catch );
83+ };
6884
69- return call_user_func ($ delegate );
85+ return (new Firewall ($ this ->app , [
86+ 'challenge ' => $ challenge ,
87+ 'authenticate ' => $ authenticate ,
88+ 'firewall ' => $ this ->container ['firewall ' ],
89+ ]))
90+ ->handle ($ request , $ type , $ catch );
7091 }
7192
7293 private function setupContainer (array $ options = array ())
@@ -77,7 +98,9 @@ private function setupContainer(array $options = array())
7798 );
7899 }
79100
80- $ c = new Pimple ;
101+ $ c = new Pimple ([
102+ 'firewall ' => [],
103+ ]);
81104
82105 foreach ($ options as $ name => $ value ) {
83106 if (in_array ($ name , ['authenticator ' ])) {
0 commit comments