12

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?

Maciej Ziarko
  • 11,494
  • 13
  • 48
  • 69
Ricardo Pardini
  • 922
  • 7
  • 17
  • same problem here. It would be nice if AccessDecisionVoters not only return ACCESS_GRANTED or ACCESS_DENIED but return an AccessDeniedDecision which can hold a reason/cause – Janning Vygen Mar 08 '13 at 10:13
  • 1
    I created a jira issue: https://jira.springsource.org/browse/SEC-2148 – Janning Vygen Mar 08 '13 at 10:33

3 Answers3

5

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

Maciej Ziarko
  • 11,494
  • 13
  • 48
  • 69
1

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"

Gokhan Oner
  • 3,237
  • 19
  • 25
1

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

Jan Tomášek
  • 135
  • 10