These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Created by PhpStorm. |
||
4 | * User: dsmrt |
||
5 | * Date: 1/10/18 |
||
6 | * Time: 11:52 AM |
||
7 | */ |
||
8 | |||
9 | namespace flipbox\saml\sp\controllers; |
||
10 | |||
11 | |||
12 | use craft\web\Controller; |
||
13 | use flipbox\saml\core\exceptions\InvalidMetadata; |
||
14 | use flipbox\saml\sp\records\ProviderRecord; |
||
15 | use flipbox\saml\sp\Saml; |
||
16 | use Craft; |
||
17 | use flipbox\saml\core\helpers\SerializeHelper; |
||
18 | use flipbox\saml\sp\services\bindings\Factory; |
||
19 | use LightSaml\Model\Protocol\AuthnRequest; |
||
20 | use yii\web\HttpException; |
||
21 | |||
22 | class LoginController extends Controller |
||
23 | { |
||
24 | |||
25 | protected $allowAnonymous = [ |
||
26 | 'actionIndex', |
||
27 | 'actionRequest', |
||
28 | ]; |
||
29 | |||
30 | public $enableCsrfValidation = false; |
||
31 | |||
32 | /** |
||
33 | * @param \yii\base\Action $action |
||
34 | * @return bool |
||
35 | */ |
||
36 | public function beforeAction($action) |
||
37 | { |
||
38 | if ($action->actionMethod === 'actionIndex') { |
||
39 | return true; |
||
40 | } |
||
41 | return parent::beforeAction($action); |
||
42 | } |
||
43 | |||
44 | /** |
||
45 | * @return \yii\web\Response |
||
46 | * @throws HttpException |
||
47 | * @throws \Exception |
||
48 | * @throws \Throwable |
||
49 | * @throws \craft\errors\ElementNotFoundException |
||
50 | * @throws \flipbox\saml\core\exceptions\InvalidMessage |
||
51 | * @throws \yii\base\Exception |
||
52 | * @throws \yii\base\UserException |
||
53 | */ |
||
54 | public function actionIndex() |
||
55 | { |
||
56 | |||
57 | $response = Factory::receive(Craft::$app->request); |
||
58 | |||
59 | if (Saml::getInstance()->getSession()->getRequestId() !== $response->getInResponseTo()) { |
||
60 | throw new HttpException(400, "Invalid request"); |
||
61 | } |
||
62 | |||
63 | /** |
||
64 | * Really don't know how we'd get here but just shutting things down now. |
||
65 | * If you fail login at the idp I'd hope they'd just make you continue to try on their end |
||
66 | * but just incase. |
||
67 | * |
||
68 | * In this case, you may want to have a good custom 403 error page to reach out to someone |
||
69 | * to figure out why the person is having issues logging in. |
||
70 | */ |
||
71 | if (! $response->getStatus() || ! $response->getStatus()->isSuccess()) { |
||
72 | throw new HttpException(403, "Login failed!"); |
||
73 | } |
||
74 | |||
75 | Saml::getInstance()->getLogin()->login($response); |
||
76 | |||
77 | //get relay state but don't error! |
||
78 | $relayState = \Craft::$app->request->getQueryParam('RelayState') ?: \Craft::$app->request->getBodyParam('RelayState'); |
||
79 | try { |
||
80 | $redirect = base64_decode($relayState); |
||
81 | } catch (\Exception $e) { |
||
82 | $redirect = \Craft::$app->getUser()->getReturnUrl(); |
||
83 | } |
||
84 | |||
85 | return $this->redirect($redirect); |
||
86 | } |
||
87 | |||
88 | |||
89 | /** |
||
90 | * @throws \flipbox\saml\core\exceptions\InvalidMetadata |
||
91 | */ |
||
92 | public function actionRequest() |
||
93 | { |
||
94 | /** @var ProviderRecord $idp */ |
||
95 | if (! $idp = Saml::getInstance()->getProvider()->findByIdp()) { |
||
96 | throw new InvalidMetadata('IDP Metadata Not found!'); |
||
97 | } |
||
98 | |||
99 | /** |
||
100 | * @var $authnRequest AuthnRequest |
||
101 | */ |
||
102 | $authnRequest = Saml::getInstance()->getAuthnRequest()->create($idp); |
||
103 | |||
104 | /** |
||
105 | * Extra layer of security, save the id and check it on the return. |
||
106 | */ |
||
107 | Saml::getInstance()->getSession()->setRequestId( |
||
108 | $authnRequest->getID() |
||
109 | ); |
||
110 | |||
111 | $authnRequest->setRelayState( |
||
112 | SerializeHelper::toBase64(Craft::$app->getUser()->getReturnUrl()) |
||
113 | ); |
||
114 | |||
115 | |||
116 | Factory::send($authnRequest, $idp); |
||
117 | |||
118 | exit; |
||
0 ignored issues
–
show
|
|||
119 | } |
||
120 | |||
121 | } |
An exit expression should only be used in rare cases. For example, if you write a short command line script.
In most cases however, using an
exit
expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.