Skip to content

Commit 88a266e

Browse files
monkeyiqtvdijen
andauthored
Draft: Another way to return a 405 if calling SSO with HEAD req. (#2481)
* Another way to return a 405 if calling SSO with HEAD req. This relates to #2475 * downgrade to debug * Report 405 for all other methods * Move the allowedMethods array into the route definition. This would require a few rotues calling into headRequestNotAllowed if the allowedMethods are different. * Rename controller-method It will not just handle head-requests, also OPTIONS, TRACE, etc. * Fix lock-file * Move to separate controller-class and re-use on all SAML-endpoints * Fix alphabetical order --------- Co-authored-by: Tim van Dijen <tvdijen@gmail.com>
1 parent 8ee8d43 commit 88a266e

4 files changed

Lines changed: 160 additions & 1 deletion

File tree

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
"symfony/config": "^6.4",
7272
"symfony/console": "^6.4",
7373
"symfony/dependency-injection": "^6.4",
74+
"symfony/expression-language": "~6.4.0",
7475
"symfony/filesystem": "^6.4",
7576
"symfony/finder": "^6.4",
7677
"symfony/framework-bundle": "^6.4",

composer.lock

Lines changed: 65 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

modules/saml/routing/routes/routes.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,29 @@ saml-sp-wrongAuthnContextClassRef:
3535
}
3636
methods: [GET]
3737

38+
saml-sp-assertionConsumerService-method-not-allowed:
39+
path: /sp/saml2-acs.php/{sourceId}
40+
defaults: {
41+
_controller: 'SimpleSAML\Module\saml\Controller\Exception::methodNotAllowed',
42+
allowedMethods: ['GET', 'POST']
43+
}
44+
condition: "context.getMethod() not in ['GET', 'POST']"
45+
3846
saml-sp-assertionConsumerService:
3947
path: /sp/saml2-acs.php/{sourceId}
4048
defaults: {
4149
_controller: 'SimpleSAML\Module\saml\Controller\ServiceProvider::assertionConsumerService'
4250
}
4351
methods: [GET, POST]
4452

53+
saml-sp-singleLogoutService-method-not-allowed:
54+
path: /sp/saml2-logout.php/{sourceId}
55+
defaults: {
56+
_controller: 'SimpleSAML\Module\saml\Controller\Exception::methodNotAllowed',
57+
allowedMethods: ['GET', 'POST']
58+
}
59+
condition: "context.getMethod() not in ['GET', 'POST']"
60+
4561
saml-sp-singleLogoutService:
4662
path: /sp/saml2-logout.php/{sourceId}
4763
defaults: {
@@ -64,13 +80,29 @@ saml-legacy-sp-metadata:
6480
}
6581
methods: [GET]
6682

83+
websso-single-sign-on-method-not-allowed:
84+
path: /idp/singleSignOnService
85+
defaults: {
86+
_controller: 'SimpleSAML\Module\saml\Controller\Exception::methodNotAllowed',
87+
allowedMethods: ['GET', 'POST']
88+
}
89+
condition: "context.getMethod() not in ['GET', 'POST']"
90+
6791
websso-single-sign-on:
6892
path: /idp/singleSignOnService
6993
defaults: {
7094
_controller: 'SimpleSAML\Module\saml\Controller\WebBrowserSingleSignOn::singleSignOnService'
7195
}
7296
methods: [GET, POST]
7397

98+
websso-artifact-resolution-method-not-allowed:
99+
path: /idp/artifactResolutionService
100+
defaults: {
101+
_controller: 'SimpleSAML\Module\saml\Controller\Exception::methodNotAllowed',
102+
allowedMethods: ['GET', 'POST']
103+
}
104+
condition: "context.getMethod() not in ['GET', 'POST']"
105+
74106
websso-artifact-resolution:
75107
path: /idp/artifactResolutionService
76108
defaults: {
@@ -85,6 +117,14 @@ websso-metadata:
85117
}
86118
methods: [GET]
87119

120+
websso-single-logout-method-not-allowed:
121+
path: /idp/singleLogout
122+
defaults: {
123+
_controller: 'SimpleSAML\Module\saml\Controller\Exception::methodNotAllowed',
124+
allowedMethods: ['GET', 'POST']
125+
}
126+
condition: "context.getMethod() not in ['GET', 'POST']"
127+
88128
websso-single-logout:
89129
path: /idp/singleLogout
90130
defaults: {
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\Module\saml\Controller;
6+
7+
use SimpleSAML\{Configuration, Logger};
8+
use Symfony\Component\HttpFoundation\Request;
9+
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
10+
11+
use function implode;
12+
use function sprintf;
13+
14+
/**
15+
* Controller class for handling 'method not allowed' on SAML 2.0 endpoints.
16+
*
17+
* @package simplesamlphp/simplesamlphp
18+
*/
19+
class Exception
20+
{
21+
/**
22+
* Controller constructor.
23+
*
24+
* It initializes the global configuration for the controllers implemented here.
25+
*
26+
* @param \SimpleSAML\Configuration $config The configuration to use by the controllers.
27+
*/
28+
public function __construct(
29+
protected Configuration $config,
30+
) {
31+
}
32+
33+
34+
/**
35+
* @param string[] $allowedMethods
36+
* @return \SimpleSAML\HTTP\RunnableResponse
37+
*/
38+
public function methodNotAllowed(array $allowedMethods): never
39+
{
40+
Logger::debug('Handling a HEAD request by returning method not allowed...');
41+
42+
$request = Request::createFromGlobals();
43+
44+
// These are the allowed methods from routes.yml
45+
$message = sprintf(
46+
'No route found for "%s %s": Method Not Allowed (Allow: %s)',
47+
$request->getMethod(),
48+
$request->getUriForPath($request->getPathInfo()),
49+
implode(', ', $allowedMethods),
50+
);
51+
52+
throw new MethodNotAllowedHttpException($allowedMethods, $message);
53+
}
54+
}

0 commit comments

Comments
 (0)