how to use Shiro in Spring MVC with java-config (just for the newer )

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

how to use Shiro in Spring MVC with java-config (just for the newer )

Mike Guo
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

















Loading...