Open kmacpher67 opened 10 years ago
It looks like spring security fires notifications on authorization events similar to how it handles authentications. It should be fairly easy to extend the plugin to log these as well. They might not fit into the existing table very well though. I wonder if it makes sense to have two tables, one for authorizations and one for authentications.
Here's a pointer to the event class: http://docs.spring.io/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/access/event/AbstractAuthorizationEvent.html
I was thinking it would be good to have Granted Authorities (authorities) column to track the user's current roles and maybe a extra custom stuff/messages column in the domain object (which could be used for authorization extras), the WebAuthenticationDetails has a custom method for some other goodies: doPopulateAdditionalInformation.
AuthorizationFailureEvent is constructed using: (Object secureObject, Collection
The only missing is the extras like: GrantedAuthorities (which would be nice to have in Authentication cause we have dynamic GA based on user's current active profile).
getConfigAttributes() will get representation of the configuration attribute data like url, privs, that AccessDecisionManager used to evaluate or vote for the event (maybe we want to log these goodies, but maybe that's an extra stuff column or as Spring calls it "AdditionalInformation" ).
So I wrote a new class, but used the same table to write the data to.
class SpringSecurityAuthZAuditLogger extends LoggerListener{
void onApplicationEvent(AbstractAuthorizationEvent event){
log.debug(" onApplicationEvent " + event)
logAuthenticationEvent(event.getAccessDeniedException().getMessage(), event.authentication, event.authentication?.details?.remoteAddress, event.authentication.principal?.authorities.toString())
}
Note: I put the authorties into switchedUsername just for brevity sake.
Pretty cool, just goes right in there, like it was meant to, your call on a new domain object/table. IMHO you could use the existing one it's just another security event message like logout.
15 2014-01-22 14:37:13.948 Access is denied 10.0.8.162 62C501C31F5F7ACC012C5A25018E18B1 [ROLE_USER] testuser
16 2014-01-22 14:39:59.482 Access is denied 127.0.0.1 null [ROLE_ANONYMOUS] __grails.anonymous.user__
17 2014-01-22 14:40:05.754 Access is denied 127.0.0.1 BA6D4CB12A931067BCE28CDC0A7A5942 [ROLE_ANONYMOUS] __grails.anonymous.user__
The samples seem mostly authentication oriented. Is there security event native fired when a user attempts an unauthorized resource /reallyImportant [ROLE_ADMIN] but a regular user attempts to access /reallyImportant and gets the authorization exception. "Sorry, you're not authorized to view this page."
My experience is that Spring Security is pretty lacking the "reason" as the voters context is basically lost. But can we atleast catch the basic "AccessDeniedException" ?
[bio-8080-exec-5] DEBUG - ess.intercept.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /secure/important; Attributes: [ROLE_ADMIN] [bio-8080-exec-5] DEBUG - ess.intercept.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@ffa9ccdf: Principal: grails.plugin.springsecurity.userdetails.GrailsUser@bbb4975d: Username: testuser; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@59b2: RemoteIpAddress: 10.0.8.162; SessionId: null; Granted Authorities: ROLE_USER [bio-8080-exec-5] DEBUG - ess.hierarchicalroles.RoleHierarchyImpl - getReachableGrantedAuthorities() - From the roles [ROLE_USER] one can reach [ROLE_USER] in zero or more steps. [bio-8080-exec-5] DEBUG - y.web.access.ExceptionTranslationFilter - Access is denied (user is not anonymous); delegating to AccessDeniedHandler org.springframework.security.access.AccessDeniedException: Access is denied at grails.plugin.springsecurity.access.vote.AuthenticatedVetoableDecisionManager.deny(AuthenticatedVetoableDecisionManager.java:113) at grails.plugin.springsecurity.access.vote.AuthenticatedVetoableDecisionManager.checkOtherVoters(AuthenticatedVetoableDecisionManager.java:105) at grails.plugin.springsecurity.access.vote.AuthenticatedVetoableDecisionManager.decide(AuthenticatedVetoableDecisionManager.java:44) at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.java:53) at grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter.doFilter(RequestHolderAuthenticationFilter.java:49) at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:82) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918) at java.lang.Thread.run(Thread.java:662)