Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to obtain the 'reason'/cause for an AccessDeniedException in Spring Security?

We're using Spring Security 3.1.3-RELEASE with method-level security. It works perfectly.

I'd like to log, and maybe show to the user, why he is getting denied access.

Using a org.springframework.security.web.access.AccessDeniedHandlerImpl subclass, I can get a reference to the org.springframework.security.access.AccessDeniedException thrown, but I can't find a way to determine what caused it (eg, 'Missing role ROLE_ADMIN' or something to that effect).

Am I missing something, or does it simply not exist?

like image 868
Ricardo Pardini Avatar asked Nov 06 '12 18:11

Ricardo Pardini


3 Answers

Unfortunately, it is not possible with default implementations available in Spring Security.

I investigated source code and...

MethodSecurityInterceptor is responsible for protecting method invocations. It delegates access decisions to AccessDecisionManager. I checked every implementation of AccessDecisionManager available out of box.

  • AffirmativeBased
  • ConsensusBased
  • UnanimousBased

Each of them throws AccessDeniedException exception in similar way.

case AccessDecisionVoter.ACCESS_DENIED:
                throw new AccessDeniedException(
                      messages.getMessage("AbstractAccessDecisionManager.accessDenied",
                      "Access is denied")
                 );

AbstractAccessDecisionManager.accessDenied is name of the message, which can be localized.

For English it is:

AbstractAccessDecisionManager.accessDenied=Access is denied

There are several languages available out of box, and you can make you own translations, but...

That's all, no more information about reasons of exception.

More information about localization of exception messages:

http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#localization

like image 76
Maciej Ziarko Avatar answered Oct 19 '22 00:10

Maciej Ziarko


I also created a jira issue for that: https://jira.spring.io/browse/SEC-3104

@PreAuthorize, @PostAuthorize, @Secured annotation can have a parameter to point custom message property in order to set detailed & more user friendly exception messages.

This could also be done by providing a param. to define an class name that extends AccessDeniedException to raise to you let users handle the rest.

This way, while processing complex rules like

@PreAuthorize("record.createuser != authentication.getName()")

We can get a defined error like

"You cannot process a record that you created."" etc. instead of "Access is denied"

like image 39
Gokhan Oner Avatar answered Oct 19 '22 00:10

Gokhan Oner


I have implemented a solution which works (only) for authorization annotations used in the API layer (e.g. with @RequestMapping). See my answer here: https://stackoverflow.com/a/64846057/4413638

like image 1
Jan Tomášek Avatar answered Oct 18 '22 23:10

Jan Tomášek