-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Convert InsufficientAuthenticationException to HttpAccessDeniedException #8467
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This is weird. It should be handled by the ExceptionController of the security component already |
Please explain a little bit particularly why. |
https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php is the exception listener I'm talking about. The Firewall is registering on the |
Oh, I see. It causes because my configuration hasn't login_form. But security component hasn't ExceptionController. |
@Koc can you confirm there is no framework problem here and close this issue? |
I cann't confitm that. |
@Koc then can you point the real issue and write a failing test? |
I think that better ask @schmittjoh is this fw problem or no. |
Might be related: #9823 |
…eniedException if is not first exception (fabpot) This PR was merged into the 2.3 branch. Discussion ---------- [Security] Fix ExceptionListener to catch correctly AccessDeniedException if is not first exception | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #9544, #8467?, #9823 | License | MIT | Doc PR | Same as #9823 but with some refactoring of the code and with some unit tests. When merging to 2.4, the unit tests can be simplified a bit. Commits ------- 172fd63 [Security] made code easier to understand, added some missing unit tests 616b6c5 [Security] fixed error 500 instead of 403 if previous exception is provided to AccessDeniedException
No, this issue isn't fixed. I got
|
Tryed on the 0285bfd revision |
I can confirm this with Symfony 2.4.2 and using simple_preauth. |
Also confirming for 2.4.2, I think I know how this occurs in my setup: I have an Api which uses a token supplied via a header to authenticate. There is no authentication entry point: if there's no token supplied, a 401 response should be returned directly. This line shows that the exception is re-thrown when this is the case. |
Other problem: I'm logged via rememberme. Throwing |
@Koc this is an issue in your login page. If you are authenticated through remember_me only, you should still be able to access the login form to login again as a fully authenticated user |
@pkruithof did you find workaround for this? |
@nostrzak yes I did: I added an exception listener that checks for these exceptions and sets the right response: https://github.com/financial-media/FMKeystoneBundle/blob/master/src/FM/KeystoneBundle/EventListener/ExceptionListener.php The listener must have a high priority, else it's picked up by the firewall listener (IIRC). |
I don't know if I was blind before but in the cookbok entry there is section exactly about this. Just for reference. Ping: @pkruithof |
Seems it was added in 2.4, I never noticed it, thanks for the link! |
Can we close this one? |
@fabpot no, please see my comment #8467 (comment) above |
@fabpot Can confirm this is an issue when using simple_preauth and the anonymous firewall flag. |
To get this issue moving again, I set up a symfony-standard branch with a failing test: https://github.com/pkruithof/symfony-standard/tree/issue-8467-invalid-status-codes Basically, I've set up two firewalls with two authentication mechanisms. The first one is stateless username/password authentication via a POST request with a JSON body, like this: curl -XPOST -d '{"username":"foo","password":"bar"}' http://localhost/api/tokens This returns a token which can be used in the second authentication mechanism, using it as a query parameter. The second mechanism is set up exactly as described in this cookbook article. The difference between the two is that the second uses the
So hopefully with this failing test we can actually fix this issue. As I stated earlier, I think this is because the failing firewall does not have an entry point, which is a design choice (there is no login form or anything in this example). And I guess the |
Confirming. Same behaviour for me. InsufficientAuthenticationException is returned with 500 code. |
@pkruithof thank you for providing code that would reproduce this issue. Your case could be easily solved by doing what was previously suggested by @dmaicher and the docs - catching the I'm assuming @Koc's problem has the same root cause as @pkruithof (please provide some code if this is not the case). To summarise options to solve this issue (already mentioned in the comments above), we could:
From the end-user's perspective option 2 would be the best, as he wouldn't have to do anything to get a correct response. It is a behaviour change though, and we need to consider if this is a bug fix or could it be a BC break (could anyone rely on this behaviour)? If option 2 is not viable, then I'd vote for option 1. |
@jakzal we've since implemented the third option (entry point). However I do still think this is a workaround, rather than a solution. As I mentioned before:
The entry point interface clearly states that it's:
So when returning a 401 other than http basic auth (which provides a login form in the browser), the response does not start any form of authentication, but rather denies access.
I agree. |
Also having the same issue, I'm giving ROLES depending on the current application theme (using the LiipThemeBundle) to anonymous users. I don't have login form at all. I have several actions that should be only be accessed for a give theme.
When browsing THEME2 returns the same error 500:
|
I am encountering this issue with the FrameworkExtraBundle's @Security annotation. When the expression fails, the SecurityListener throws an AccessDeniedException as expected, but it is not handled because I do not have Because the exceptions are not occurring in the authentication listeners for me, I am not able to do points 1 or 2 proposed by @jakzal. The suggested EntryPoint implementation added to my firewall fixed the problem. security:
api:
anonymous: true
entry_point: "system.api_entry" <?php
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
class ApiEntryPoint implements AuthenticationEntryPointInterface
{
public function start(Request $request, AuthenticationException $authException = null)
{
return new JsonResponse([
'error' => JsonResponse::HTTP_FORBIDDEN,
'message' => $authException ? $authException->getMessage() : 'Access Denied'
], JsonResponse::HTTP_FORBIDDEN);
}
} |
Any update on this? |
@goetas Sorry, but which solution ? |
I'm still seeing this issue in 3.3 using LexikJWTAuthenticationBundle |
@weaverryan @chalasr @stof as you are mergers of the security component: What do you think? @jakzal proposed some options here: #8467 (comment) One more idea would be to throw an I could work on a patch if we agree on a solution 😊 |
I had the same issue on Pattern always must be restrictive at the start, and be degressive firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
backend:
anonymous: ~
pattern: ^/admin
provider: admin
form_login:
login_path: admin_login
check_path: admin_login
default_target_path: admin_dashboard
public:
anonymous: ~
pattern: ^/
provider: customer
access_control:
- { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN } |
I get the same kind of error with Symfony4 + Flex (this is a proof of concept project) A sample route that return the 500 : Here is my security.yaml
Here is the action controller:
And finally the composer.json:
And maybe the way i installed the app:
Here is the project uri: https://github.com/Rebolon/php-sf-flex-webpack-encore-vuejs |
when i look at the Security component documentation https://symfony.com/doc/master/bundles/SensioFrameworkExtraBundle/annotations/security.html I can see that we have to specify the status_code if we want an HTTP Exception instead of an AccessDeniedException For my configuration it seems that the |
If this would help. I'm encountering this issue with the following configuration:
The problem is the presence |
@chaos-drone your |
…on with 401 status code (vincentchalamon) This PR was merged into the 2.8 branch. Discussion ---------- Convert InsufficientAuthenticationException to HttpException with 401 status code | Q | A | ------------- | --- | Branch? | 2.8 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed ticket | #8467 | License | MIT I was trying to implement the `json_login` authentication and test it with an API Platform project. When I call a secured endpoint without authentication, an InsufficientAuthenticationException is thrown with a 500 status code instead of a 401. After some researches with @dunglas, there is no default `entrypoint` on the security firewall. As one already exists for `form_login` in the FormLoginFactory, this component might need a default one to convert this 500 exception to a correct 401 HTTP error. This fixes #25806 (comment). Commits ------- 4503ac8 Convert InsufficientAuthenticationException to HttpException
I hope #28801 fixes this issue |
@Koc your fix is only for 2.8 or also for 3.4+ and 4+ ? |
@Rebolon it will be merged up in the other branches 😉 |
open as anonymous something like
/admin/dashboard
and got 500. Expected 403.The text was updated successfully, but these errors were encountered: