44
55use Neos \Flow \Annotations as Flow ;
66use Neos \Flow \Core \Bootstrap ;
7+ use Neos \Flow \Http \Component \ComponentContext ;
78use Neos \Flow \Http \HttpRequestHandlerInterface ;
8- use Neos \Flow \Security \Authentication \EntryPoint \WebRedirect ;
99use Neos \Flow \Security \Authentication \Provider \AbstractProvider ;
1010use Neos \Flow \Security \Authentication \TokenInterface ;
1111use Neos \Flow \Security \Context as SecurityContext ;
1212use Neos \Flow \Security \Exception \AuthenticationRequiredException ;
1313use Neos \Flow \Security \Exception \UnsupportedAuthenticationTokenException ;
14+ use Neos \Flow \Session \SessionManagerInterface ;
15+ use Neos \Utility \Exception \PropertyNotAccessibleException ;
16+ use Neos \Utility \ObjectAccess ;
17+ use Yeebase \TwoFactorAuthentication \Http \RedirectComponent ;
1418use Yeebase \TwoFactorAuthentication \Security \Authentication \Token \OtpToken ;
1519use Yeebase \TwoFactorAuthentication \Service \TwoFactorAuthenticationService ;
1620
@@ -38,18 +42,6 @@ final class TwoFactorAuthenticationProvider extends AbstractProvider
3842 */
3943 protected $ twoFactorAuthenticationService ;
4044
41- /**
42- * @Flow\InjectConfiguration(path="routes.login")
43- * @var array
44- */
45- protected $ loginRouteValues ;
46-
47- /**
48- * @Flow\InjectConfiguration(path="routes.setup")
49- * @var array
50- */
51- protected $ setupRouteValue ;
52-
5345 /**
5446 * @Flow\InjectConfiguration(path="requireTwoFactorAuthentication")
5547 * @var bool
@@ -76,7 +68,7 @@ public function authenticate(TokenInterface $authenticationToken): void
7668 }
7769 if ($ this ->twoFactorAuthenticationService ->isTwoFactorAuthenticationEnabledFor ($ account )) {
7870 if (!$ authenticationToken ->hasOtp ()) {
79- $ this ->redirectToLogin ( );
71+ $ this ->requestRedirect (RedirectComponent:: REDIRECT_LOGIN );
8072 return ;
8173 }
8274 if ($ this ->twoFactorAuthenticationService ->validateOtp ($ account , $ authenticationToken ->getOtp ())) {
@@ -90,7 +82,7 @@ public function authenticate(TokenInterface $authenticationToken): void
9082 return ;
9183 }
9284 if ($ this ->requireTwoFactorAuthentication ) {
93- $ this ->redirectToSetup ( );
85+ $ this ->requestRedirect (RedirectComponent:: REDIRECT_SETUP );
9486 } else {
9587 /** @noinspection PhpUnhandledExceptionInspection */
9688 $ authenticationToken ->setAuthenticationStatus (TokenInterface::AUTHENTICATION_SUCCESSFUL );
@@ -99,49 +91,24 @@ public function authenticate(TokenInterface $authenticationToken): void
9991 }
10092
10193 /**
102- * Triggers a redirect to the 2FA login route configured at routes.login or throws an exception if the configuration is missing/incorrect
103- */
104- private function redirectToLogin (): void
105- {
106- try {
107- $ this ->validateRouteValues ($ this ->loginRouteValues );
108- } catch (\InvalidArgumentException $ exception ) {
109- throw new \RuntimeException ('Missing/invalid routes.login configuration: ' . $ exception ->getMessage (), 1550660144 , $ exception );
110- }
111- $ this ->redirect ($ this ->loginRouteValues );
112- }
113-
114- /**
115- * Triggers a redirect to the 2FA setup route configured at routes.setup or throws an exception if the configuration is missing/incorrect
94+ * Triggers a redirect by setting the corresponding HTTP component parameter for the @see RedirectComponent to pick up
95+ *
96+ * @param string $target one of the RedirectComponent::REDIRECT_* constants
11697 */
117- private function redirectToSetup ( ): void
98+ private function requestRedirect ( string $ target ): void
11899 {
119- try {
120- $ this ->validateRouteValues ($ this ->setupRouteValue );
121- } catch (\InvalidArgumentException $ exception ) {
122- throw new \RuntimeException ('Missing/invalid routes.setup configuration: ' . $ exception ->getMessage (), 1550660178 , $ exception );
123- }
124- $ this ->redirect ($ this ->setupRouteValue );
125- }
126-
127- private function validateRouteValues (array $ routeValues ): void
128- {
129- $ requiredRouteValues = ['@package ' , '@controller ' , '@action ' ];
130- foreach ($ requiredRouteValues as $ routeValue ) {
131- if (!array_key_exists ($ routeValue , $ routeValues )) {
132- throw new \InvalidArgumentException (sprintf ('Missing "%s" route value ' , $ routeValue ), 1550660039 );
133- }
134- }
135- }
136-
137- private function redirect (array $ routeValues ): void {
138100 $ requestHandler = $ this ->bootstrap ->getActiveRequestHandler ();
139101 if (!$ requestHandler instanceof HttpRequestHandlerInterface) {
140102 throw new \RuntimeException ('This provider only supports HTTP requests ' , 1549985779 );
141103 }
142- $ webRedirect = new WebRedirect ();
143- $ webRedirect ->setOptions (['routeValues ' => $ routeValues ]);
144- /** @noinspection PhpUnhandledExceptionInspection */
145- $ webRedirect ->startAuthentication ($ requestHandler ->getHttpRequest (), $ requestHandler ->getHttpResponse ());
104+ try {
105+ $ componentContext = ObjectAccess::getProperty ($ requestHandler , 'componentContext ' , true );
106+ } catch (PropertyNotAccessibleException $ e ) {
107+ throw new \RuntimeException ('Faild to extract ComponentContext from RequestHandler ' , 1568188386 , $ e );
108+ }
109+ if (!$ componentContext instanceof ComponentContext) {
110+ throw new \RuntimeException ('Faild to extract ComponentContext from RequestHandler ' , 1568188387 );
111+ }
112+ $ componentContext ->setParameter (RedirectComponent::class, 'redirect ' , $ target );
146113 }
147114}
0 commit comments