扫描完项目的漏洞后决定启用ssl,修改完,登录之后会重定向到登录页。
经过一段时间的debug,发现过滤器里面subject.getPrincipal()为空了。
继续找原因,但是找了大半天没找到,决定用其他项目改ssl试试,结果那个项目改完可以正常登录。
对比了一下两个项目的区别在于shiro的SecurityManager,成功的那个用的是SessionManager,失败那个用的是CacheManager,把CacheManager改成SessionManager也能成功登录了。
对了,CacheManager用的是EhCache,不知道是不是EhCache不支持ssl(查了很久没查到),虽然改完后能成功登录了,但是根本没有搞明白是怎么一回事,希望有大神能解答一下疑惑。
下面把修改完后的代码贴一下:
@Configuration
public class ShiroConfig {
@Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
@Bean
public EhCacheManager getEhCacheManager() {// 这个已经不需要了
EhCacheManager em = new EhCacheManager();
em.setCacheManagerConfigFile("classpath:ehcache-shiro.xml");
return em;
}
@Bean(name = "credentialsMatcher")
public MyCredentialsMatcher credentialsMatcher() {
return new MyCredentialsMatcher();
}
@Bean(name = "myShiroRealm")
public MyShiroRealm myShiroRealm(@Qualifier("credentialsMatcher") MyCredentialsMatcher matcher, EhCacheManager cacheManager) {
MyShiroRealm realm = new MyShiroRealm();
realm.setCredentialsMatcher(matcher);
realm.setCacheManager(cacheManager);
return realm;
}
@Bean(name = "sessionIdGenerator")
public JavaUuidSessionIdGenerator sessionIdGenerator() {
return new JavaUuidSessionIdGenerator();
}
@Bean(name = "sessionIdCookie")
public SimpleCookie sessionIdCookie() {
SimpleCookie cookie = new SimpleCookie();
cookie.setName("WEBSID");
cookie.setHttpOnly(true);
cookie.setMaxAge(1800);// 单位:秒
return cookie;
}
@Bean(name = "sessionDao")
public EnterpriseCacheSessionDAO sessionDao() {
EnterpriseCacheSessionDAO sessionDao = new EnterpriseCacheSessionDAO();
sessionDao.setActiveSessionsCacheName("shiro-activeSessionCache");
sessionDao.setSessionIdGenerator(new JavaUuidSessionIdGenerator());
return sessionDao;
}
@Bean(name = "sessionManager")
public DefaultWebSessionManager sessionManager() {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setGlobalSessionTimeout(1800000);// 单位:毫秒
sessionManager.setDeleteInvalidSessions(true);
sessionManager.setSessionValidationSchedulerEnabled(true);
// sessionManager.setSessionValidationScheduler(new QuartzSessionValidationScheduler());
sessionManager.setSessionDAO(sessionDao());
sessionManager.setSessionIdCookieEnabled(true);
sessionManager.setSessionIdCookie(sessionIdCookie());
return sessionManager;
}
@Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean
public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
daap.setProxyTargetClass(true);
return daap;
}
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(MyShiroRealm myShiroRealm, DefaultWebSessionManager sessionManager) {
DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();
dwsm.setRealm(myShiroRealm);
dwsm.setSessionManager(sessionManager);
// 用户授权/认证信息Cache, 采用EhCache 缓存
// dwsm.setCacheManager(getEhCacheManager());
return dwsm;
}
@Bean
public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
aasa.setSecurityManager(securityManager);
return aasa;
}
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() {
@Override
protected void postProcessContext(Context context) {
SecurityConstraint constraint = new SecurityConstraint();
constraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
constraint.addCollection(collection);
context.addConstraint(constraint);
}
};
tomcat.addAdditionalTomcatConnectors(httpConnector());
return tomcat;
}
@Bean
public Connector httpConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
// Connector监听的http的端口号
connector.setPort(11086);
connector.setSecure(false);
// 监听到http的端口号后转向到的https的端口号
connector.setRedirectPort(10086);
return connector;
}
private void loadShiroFilterChain(ShiroFilterFactoryBean shiroFilterFactoryBean) {
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/api/**", "basicAuth");
filterChainDefinitionMap.put("/global/**", "anon");
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/login", "authc");
filterChainDefinitionMap.put("/index", "defaultPassword");
filterChainDefinitionMap.put("/", "defaultPassword");
filterChainDefinitionMap.put("/defaultPasswordView", "user");
filterChainDefinitionMap.put("/sysUserChangePassword", "user");
filterChainDefinitionMap.put("/getKaptchaImage", "anon");// 匿名访问
filterChainDefinitionMap.put("/**", "user");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
}
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
Map<String, Filter> filters = shiroFilterFactoryBean.getFilters();// 获取filters
filters.put("authc", new MyFormAuthenticationFilter());// 登陆密码验证
filters.put("user", new MyUserFilter());// 登陆状态验证
filters.put("defaultPassword", new MyDefaultPasswordFilter());// 默认密码验证
filters.put("basicAuth", new MyBasicAuthFileter());// Restful api的BasicAuth验证
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setSuccessUrl("/");
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
loadShiroFilterChain(shiroFilterFactoryBean);
return shiroFilterFactoryBean;
}
}