I have a Spring 4 MVC application that uses @RestController annotations for all of the endpoints. The application does not use a web.xml nor an applicationContext.xml file. Everything works perfectly fine and now I am trying to get Apache Shiro working in cooperation with everything else.
What I would like to do is have Shiro throw an exception when there is an authc/authz problem accessing any of the REST services that I have built.
So far I was able to set up a basic class set up for initializing Shiro:
@Configuration
public class ShiroInitializer {
@Bean(name = "realmLocal")
@DependsOn ("lifecycleBeanPostProcessor")
public Realm realmLocal() {
return new AuthorizingRealm() {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
return null;
}
};
}
@Bean (name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean
public org.apache.shiro.mgt.SecurityManager getSecurityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realmLocal());
return securityManager;
}
@DependsOn("lifecycleBeanPostProcessor")
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
proxyCreator.setProxyTargetClass(true);
return proxyCreator;
}
// enable shiro annotations
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(getSecurityManager());
return advisor;
}
@Bean (name = "shiroFilter")
public ShiroFilterFactoryBean getShiroFilter() {
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
shiroFilter.setSecurityManager(getSecurityManager());
Map<String, String> filters = new ConcurrentHashMap<>();
filters.put("/**", "authcBasic");
shiroFilter.setFilterChainDefinitionMap(filters);
return shiroFilter;
}
}
When I build an endpoint like this with @RequiresUser and set breakpoints in the AuthorizingRealm in the initializer, nothing seems to picked up and the message displays without kicking off any authc/authz functionality:
@RestController
@RequestMapping (value = "/")
@RequiresUser
public class RootEndpoint {
@RequestMapping (method = RequestMethod.GET)
public String doGet() throws Exception {
return "{ \"hello\": \"world\" }";
}
}
So here are my questions
- Q1 What am I missing in my configuration? Keep in mind I am trying to avoid the XML configurations if at all possible.
- Q2 After getting the basics, what can I use to throw exceptions instead of redirect the user to another page? Do I need a custom
ShiroFilterFactoryBeanof my own?