Hi, All. I am totally new for Shiro. I understood most of people can use XML configuration both for Spring MVC and Shiro.
but since Spring 3.0 + (if I am wrong, please correct me). Spring suggest the first choice is java code config for Spring MVC. so I when switch my app to SpringMVC, I tried to use Shiro with java code config, Unfortunately, there is a few document talked about this thing, even on the Shiro official site. so, I sent email out ask help in this list. thanks for Brian’s help. and thanks google , I tried Many times. finally, I make it work prefect. so, I think I should be write these down. and share with people who want to use Shiro in Springmvc with java code config. the first thing we should understand java code config, we have to use subclass the class :WebApplicationInitializer for register filter for Shiro. also, we have to subclass AbstractAnnotationConfigDispatcherServletInitializer for springmvc and load the mainly configuration files. you can do these in one class too. but I like use two. one is for springmvc and another one is just for Shiro. here’s code: class: WebApplicationInitializer, it is just for Spring MVC public class WebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class<?>[] { RootConfig.class }; } @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[] { MvcConfiguration.class }; } @Override protected String[] getServletMappings() { return new String[] { "/" }; } } class: WebApplicationForShiroInitializer, this is just for Shiro. public class WebApplicationForShiroInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { FilterRegistration.Dynamic shiroFilter = servletContext.addFilter("shiroFilter", DelegatingFilterProxy.class); shiroFilter.setInitParameter("targetFilterLifecycle", "true"); shiroFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*"); } } since Servlet 3.0, the container can be found class implements interface : WebApplicationInitializer by automatic. and use it for configuration instead web.xml so, let’s say, we are ready for web.xml(actually, we use two class for web.xml). right now, we need configuration the Shiro. I put the Shiro configuration into Rootconfig.class here’s the Code for RootConfig @Configuration @ComponentScan("com.puyangnet.customer.qingfei.beans") @PropertySource("classpath:druid.properties") public class RootConfig implements EnvironmentAware { //define the Database source @Bean(name="dataSource") public DruidDataSource getDataSource() { DruidDataSource myDataSource = new DruidDataSource(); myDataSource.setUrl(load("druid.url")); myDataSource.setUsername(load("druid.username")); myDataSource.setPassword(load("druid.password")); myDataSource.setInitialSize(loadInt("druid.initialSize")); myDataSource.setMinIdle(loadInt("druid.minIdle")); myDataSource.setMaxActive(loadInt("druid.maxActive")); myDataSource.setMaxWait(loadInt("druid.maxWait")); myDataSource.setTimeBetweenEvictionRunsMillis( loadLong("druid.timeBetweenEvictionRunsMillis")); myDataSource.setMinEvictableIdleTimeMillis( loadLong("druid.minEvictableIdleTimeMillis") ); myDataSource.setValidationQuery( load("druid.validationQuery") ); myDataSource.setTestWhileIdle( loadBoolean("druid.testWhileIdle") ); myDataSource.setTestOnBorrow( loadBoolean("druid.testOnBorrow") ); myDataSource.setTestOnReturn( loadBoolean("druid.testOnBorrow") ); myDataSource.setPoolPreparedStatements( loadBoolean("druid.poolPreparedStatements") ); LOGGER.info(myDataSource); return myDataSource; } //define ShiroFilter @Bean(name="shiroFilter") public ShiroFilterFactoryBean getShiroFilterFactoryBean() { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setLoginUrl("/login"); shiroFilterFactoryBean.setSecurityManager(securityManager()); shiroFilterFactoryBean.setSuccessUrl("/home”); //define some filter for rules shiroFilterFactoryBean.setFilterChainDefinitionMap( GetPropertiesToHashMap.getMap("shirofilter.properties") ); return shiroFilterFactoryBean; } //define SecurityManager. @Bean public DefaultWebSecurityManager securityManager() { //use Native Session SessionManager sessionManager = new DefaultWebSessionManager(); //use Memory Cache Manager CacheManager cacheManager = new MemoryConstrainedCacheManager(); DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myRealm()); securityManager.setSessionManager(sessionManager); securityManager.setCacheManager(cacheManager); return securityManager; } //define the Realm that by yourself. //most of you just change the database query sql, you can //read the code for JdbcRealm @Bean public CustomJDBCRealm myRealm() { CustomJDBCRealm realm = new CustomJDBCRealm(); realm.setCredentialsMatcher(bcryptPasswordMatcher()); realm.setDataSource(getDataSource()); return realm; } //if you don’t use Bcrypt, just ignore this one @Bean public BcryptPasswordMatcher bcryptPasswordMatcher() { return new BcryptPasswordMatcher(); } @Bean public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } @Bean @DependsOn(value="lifecycleBeanPostProcessor") public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { return new DefaultAdvisorAutoProxyCreator(); } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() { AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); advisor.setSecurityManager(securityManager()); return advisor; } // it is not related with Shiro public String load(String propertyName) { return env.getRequiredProperty(propertyName); } // it is not related with Shiro public int loadInt(String propertyName) { return env.getRequiredProperty(propertyName, Integer.class); } // it is not related with Shiro public long loadLong(String propertyName) { return env.getRequiredProperty(propertyName, Long.class); } // it is not related with Shiro public boolean loadBoolean(String propertyName) { return env.getRequiredProperty(propertyName, Boolean.class); } @Override public void setEnvironment(Environment environment) { this.env = environment; } private Environment env; private static final Logger LOGGER = LogManager.getLogger(RootConfig.class.getName()); } and another thing we use a help class for get all properties to a hash map public class GetPropertiesToHashMap implements Serializable { public static final HashMap<String, String> getMap(String fileName) { ClassPathResource resource = new ClassPathResource(fileName); Properties properties = new Properties(); if ( resource.exists() ) { try { properties.load(resource.getInputStream()); HashMap<String, String> testMap = new HashMap<String, String>(); Set<Entry<Object, Object>> set = properties.entrySet(); Iterator<Map.Entry<Object, Object>> it = set.iterator(); String key = null, value = null; while (it.hasNext()) { Entry<Object, Object> entry = it.next(); key = String.valueOf(entry.getKey()); value = String.valueOf(entry.getValue()); key = key == null ? key : key.trim(); value = value == null ? value : value.trim(); // 将key-value放入map中 LOGGER.info("Key:" + key); LOGGER.info("Value: " + value); testMap.put(key, value); } return testMap; } catch ( IOException e) { LOGGER.error(e.getMessage()); return null; } } else { return null; } } private static final Logger LOGGER = LogManager.getLogger(GetPropertiesToHashMap.class.getName()); private static final long serialVersionUID = -4052711977651801603L; } the filter configuration file content: #main path configuration. it is global security configuration too /css/*=anon /js/**=anon /images/**=anon /lib/**=anon /check-user-by-name/**=anon /submit-login=anon /login=anon /**=authc #the administrator will be use the whole system /**=user[admin] /**=roles[admin] have fun. everyone Mike