I was not able to work it out with Shiro annotations as I have it below. I'm
not exactly sure how DefaultAdvisorAutoProxyCreator and
AuthorizationAttributeSourceAdvisor are supposed to interact with the
creation of my Controller bean, but they definitely messed with some other
classes that were already being proxied by Spring (eg. with @Transactional). 

I also tried using a BeanPostProcessor to wrap a bean object with my own
proxy if it had any Shiro/Custom annotations, but I was unable to keep the
behavior of a bean that was already proxied, I was only able to overwrite
the proxy with my own. As in, replace a return a different object in
postProcessBeforeInitialization(). 

I asked  this question on the StackOverflow
<http://stackoverflow.com/questions/15594071/spring-intercepting-bean-creation-and-injecting-custom-proxy>
  
and there are some cool tricks you can do with Aspect Oriented Programming,
but I ended up just using HandlerInterceptor to check if a handler method
(the method adminHome() below) or its class (AdminController) had any
annotations.

Here's an example:

        public boolean preHandle(HttpServletRequest request, HttpServletResponse
response, Object handler) throws Exception {
                HandlerMethod method = (HandlerMethod) handler;
                RequiresAuthorization requiresAuthorization =
method.getMethodAnnotation(RequiresAuthorization.class);
                
                if (requiresAuthorization != null) {
                        Subject currentUser = SecurityUtils.getSubject();
                        
                        // Check each permission
                        for (String requiredPermission : 
requiresAuthorization.permissions()) {
                                PermissionResolver permissionResolver = new
WildcardPermissionResolver();
                                Permission permission =
permissionResolver.resolvePermission(requiredPermission);
                                if (!currentUser.isPermitted(permission)) {
                                        if (LOGGER.isInfoEnabled()) {
                                                String path =
request.getRequestURI().substring(request.getContextPath().length());
                                                LOGGER.info("The path '{}' 
requires authorization for '{}'.
Redirecting.", path, requiredPermission);
                                        }
                                        WebUtils.issueRedirect(request, 
response, redirectUrl);
                                        return false;
                                }
                        }
                }
                return true;
        }

The object 'handler' is an instance of HandlerMethod which is like a
Decorator for Java's Reflection class Method on which you can get a lot of
metadata, like annotations, parameter, return type, etc. In my case, I check
the annotation and do some authorization logic if it's there.

I'd like to think Spring has a workaround for this, like some listener you
can inject to add your own CGLIB MethodInterceptor or some interface to add
logic based on annotations, all this on top of possibly already existing
proxies. 




--
View this message in context: 
http://shiro-user.582556.n2.nabble.com/Shiro-annotations-on-Spring-MVC-Controllers-tp7578426p7578602.html
Sent from the Shiro User mailing list archive at Nabble.com.

Reply via email to