Pre Merge pull request !35 from CharlesSong/master

This commit is contained in:
CharlesSong 2018-11-13 19:24:55 +08:00
commit 98496ac4e6
5 changed files with 153 additions and 79 deletions

View File

@ -82,6 +82,12 @@
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
</dependency> </dependency>
<!--Lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -112,6 +112,18 @@ shiro:
dbSyncPeriod: 1 dbSyncPeriod: 1
# 相隔多久检查一次session的有效性默认就是10分钟 # 相隔多久检查一次session的有效性默认就是10分钟
validationInterval: 10 validationInterval: 10
anon:
- /favicon.ico**
- /ruoyi.png**
- /css/**
- /docs/**
- /fonts/**
- /img/**
- /ajax/**
- /js/**
- /ruoyi/**
- /druid/**
- /captcha/captchaImage**
# 防止XSS攻击 # 防止XSS攻击
xss: xss:

View File

@ -17,6 +17,13 @@
<dependencies> <dependencies>
<!--配置文件处理器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- SpringBoot Web容器 --> <!-- SpringBoot Web容器 -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>

View File

@ -1,21 +1,8 @@
package com.ruoyi.framework.config; package com.ruoyi.framework.config;
import java.util.LinkedHashMap; import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import java.util.Map;
import javax.servlet.Filter;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.configuration.ShiroProperties;
import com.ruoyi.framework.shiro.realm.UserRealm; import com.ruoyi.framework.shiro.realm.UserRealm;
import com.ruoyi.framework.shiro.session.OnlineSessionDAO; import com.ruoyi.framework.shiro.session.OnlineSessionDAO;
import com.ruoyi.framework.shiro.session.OnlineSessionFactory; import com.ruoyi.framework.shiro.session.OnlineSessionFactory;
@ -25,7 +12,23 @@ import com.ruoyi.framework.shiro.web.filter.online.OnlineSessionFilter;
import com.ruoyi.framework.shiro.web.filter.sync.SyncOnlineSessionFilter; import com.ruoyi.framework.shiro.web.filter.sync.SyncOnlineSessionFilter;
import com.ruoyi.framework.shiro.web.session.OnlineWebSessionManager; import com.ruoyi.framework.shiro.web.session.OnlineWebSessionManager;
import com.ruoyi.framework.shiro.web.session.SpringSessionValidationScheduler; import com.ruoyi.framework.shiro.web.session.SpringSessionValidationScheduler;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect; import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/** /**
* 权限配置加载 * 权限配置加载
@ -37,45 +40,8 @@ public class ShiroConfig
{ {
public static final String PREMISSION_STRING = "perms[\"{0}\"]"; public static final String PREMISSION_STRING = "perms[\"{0}\"]";
// Session超时时间单位为毫秒默认30分钟 @Autowired
@Value("${shiro.session.expireTime}") private ShiroProperties shiroProperties;
private int expireTime;
// 相隔多久检查一次session的有效性单位毫秒默认就是10分钟
@Value("${shiro.session.validationInterval}")
private int validationInterval;
// 验证码开关
@Value("${shiro.user.captchaEnabled}")
private boolean captchaEnabled;
// 验证码类型
@Value("${shiro.user.captchaType}")
private String captchaType;
// 设置Cookie的域名
@Value("${shiro.cookie.domain}")
private String domain;
// 设置cookie的有效访问路径
@Value("${shiro.cookie.path}")
private String path;
// 设置HttpOnly属性
@Value("${shiro.cookie.httpOnly}")
private boolean httpOnly;
// 设置Cookie的过期时间秒为单位
@Value("${shiro.cookie.maxAge}")
private int maxAge;
// 登录地址
@Value("${shiro.user.loginUrl}")
private String loginUrl;
// 权限认证失败地址
@Value("${shiro.user.unauthorizedUrl}")
private String unauthorizedUrl;
/** /**
* 缓存管理器 使用Ehcache实现 * 缓存管理器 使用Ehcache实现
@ -136,7 +102,7 @@ public class ShiroConfig
{ {
SpringSessionValidationScheduler sessionValidationScheduler = new SpringSessionValidationScheduler(); SpringSessionValidationScheduler sessionValidationScheduler = new SpringSessionValidationScheduler();
// 相隔多久检查一次session的有效性单位毫秒默认就是10分钟 // 相隔多久检查一次session的有效性单位毫秒默认就是10分钟
sessionValidationScheduler.setSessionValidationInterval(validationInterval * 60 * 1000); sessionValidationScheduler.setSessionValidationInterval(shiroProperties.getSession().getValidationInterval() * 60 * 1000);
// 设置会话验证调度器进行会话验证时的会话管理器 // 设置会话验证调度器进行会话验证时的会话管理器
sessionValidationScheduler.setSessionManager(sessionValidationManager()); sessionValidationScheduler.setSessionManager(sessionValidationManager());
return sessionValidationScheduler; return sessionValidationScheduler;
@ -154,7 +120,7 @@ public class ShiroConfig
// 删除过期的session // 删除过期的session
manager.setDeleteInvalidSessions(true); manager.setDeleteInvalidSessions(true);
// 设置全局session超时时间 // 设置全局session超时时间
manager.setGlobalSessionTimeout(expireTime * 60 * 1000); manager.setGlobalSessionTimeout(shiroProperties.getSession().getExpireTime() * 60 * 1000);
// 去掉 JSESSIONID // 去掉 JSESSIONID
manager.setSessionIdUrlRewritingEnabled(false); manager.setSessionIdUrlRewritingEnabled(false);
// 是否定时检查session // 是否定时检查session
@ -178,7 +144,7 @@ public class ShiroConfig
// 删除过期的session // 删除过期的session
manager.setDeleteInvalidSessions(true); manager.setDeleteInvalidSessions(true);
// 设置全局session超时时间 // 设置全局session超时时间
manager.setGlobalSessionTimeout(expireTime * 60 * 1000); manager.setGlobalSessionTimeout(shiroProperties.getSession().getExpireTime() * 60 * 1000);
// 去掉 JSESSIONID // 去掉 JSESSIONID
manager.setSessionIdUrlRewritingEnabled(false); manager.setSessionIdUrlRewritingEnabled(false);
// 定义要使用的无效的Session定时调度器 // 定义要使用的无效的Session定时调度器
@ -216,7 +182,7 @@ public class ShiroConfig
public LogoutFilter logoutFilter() public LogoutFilter logoutFilter()
{ {
LogoutFilter logoutFilter = new LogoutFilter(); LogoutFilter logoutFilter = new LogoutFilter();
logoutFilter.setLoginUrl(loginUrl); logoutFilter.setLoginUrl(shiroProperties.getUser().getLoginUrl());
return logoutFilter; return logoutFilter;
} }
@ -226,27 +192,34 @@ public class ShiroConfig
@Bean @Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager)
{ {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// Shiro的核心安全接口,这个属性是必须的 // Shiro的核心安全接口,这个属性是必须的
shiroFilterFactoryBean.setSecurityManager(securityManager); shiroFilterFactoryBean.setSecurityManager(securityManager);
// 身份认证失败则跳转到登录页面的配置 // 身份认证失败则跳转到登录页面的配置
shiroFilterFactoryBean.setLoginUrl(loginUrl); shiroFilterFactoryBean.setLoginUrl(shiroProperties.getUser().getLoginUrl());
// 权限认证失败则跳转到指定页面 // 权限认证失败则跳转到指定页面
shiroFilterFactoryBean.setUnauthorizedUrl(unauthorizedUrl); shiroFilterFactoryBean.setUnauthorizedUrl(shiroProperties.getUser().getUnauthorizedUrl());
// Shiro连接约束配置即过滤链的定义 // Shiro连接约束配置即过滤链的定义
LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
// 对静态资源设置匿名访问 // 对静态资源设置匿名访问
filterChainDefinitionMap.put("/favicon.ico**", "anon"); // filterChainDefinitionMap.put("/favicon.ico**", "anon");
filterChainDefinitionMap.put("/ruoyi.png**", "anon"); // filterChainDefinitionMap.put("/ruoyi.png**", "anon");
filterChainDefinitionMap.put("/css/**", "anon"); // filterChainDefinitionMap.put("/css/**", "anon");
filterChainDefinitionMap.put("/docs/**", "anon"); // filterChainDefinitionMap.put("/docs/**", "anon");
filterChainDefinitionMap.put("/fonts/**", "anon"); // filterChainDefinitionMap.put("/fonts/**", "anon");
filterChainDefinitionMap.put("/img/**", "anon"); // filterChainDefinitionMap.put("/img/**", "anon");
filterChainDefinitionMap.put("/ajax/**", "anon"); // filterChainDefinitionMap.put("/ajax/**", "anon");
filterChainDefinitionMap.put("/js/**", "anon"); // filterChainDefinitionMap.put("/js/**", "anon");
filterChainDefinitionMap.put("/ruoyi/**", "anon"); // filterChainDefinitionMap.put("/ruoyi/**", "anon");
filterChainDefinitionMap.put("/druid/**", "anon"); // filterChainDefinitionMap.put("/druid/**", "anon");
filterChainDefinitionMap.put("/captcha/captchaImage**", "anon"); // filterChainDefinitionMap.put("/captcha/captchaImage**", "anon");
List<String> anonList=shiroProperties.getAnon();
for(String anonUrl:anonList){
filterChainDefinitionMap.put(anonUrl, "anon");
}
// 退出 logout地址shiro去清除session // 退出 logout地址shiro去清除session
filterChainDefinitionMap.put("/logout", "logout"); filterChainDefinitionMap.put("/logout", "logout");
// 不需要拦截的访问 // 不需要拦截的访问
@ -276,7 +249,7 @@ public class ShiroConfig
public OnlineSessionFilter onlineSessionFilter() public OnlineSessionFilter onlineSessionFilter()
{ {
OnlineSessionFilter onlineSessionFilter = new OnlineSessionFilter(); OnlineSessionFilter onlineSessionFilter = new OnlineSessionFilter();
onlineSessionFilter.setLoginUrl(loginUrl); onlineSessionFilter.setLoginUrl(shiroProperties.getUser().getLoginUrl());
return onlineSessionFilter; return onlineSessionFilter;
} }
@ -297,8 +270,8 @@ public class ShiroConfig
public CaptchaValidateFilter captchaValidateFilter() public CaptchaValidateFilter captchaValidateFilter()
{ {
CaptchaValidateFilter captchaValidateFilter = new CaptchaValidateFilter(); CaptchaValidateFilter captchaValidateFilter = new CaptchaValidateFilter();
captchaValidateFilter.setCaptchaEnabled(captchaEnabled); captchaValidateFilter.setCaptchaEnabled(shiroProperties.getUser().isCaptchaEnabled());
captchaValidateFilter.setCaptchaType(captchaType); captchaValidateFilter.setCaptchaType(shiroProperties.getUser().getCaptchaType());
return captchaValidateFilter; return captchaValidateFilter;
} }
@ -308,10 +281,10 @@ public class ShiroConfig
public SimpleCookie rememberMeCookie() public SimpleCookie rememberMeCookie()
{ {
SimpleCookie cookie = new SimpleCookie("rememberMe"); SimpleCookie cookie = new SimpleCookie("rememberMe");
cookie.setDomain(domain); cookie.setDomain(shiroProperties.getCookie().getDomain());
cookie.setPath(path); cookie.setPath(shiroProperties.getCookie().getPath());
cookie.setHttpOnly(httpOnly); cookie.setHttpOnly(shiroProperties.getCookie().isHttpOnly());
cookie.setMaxAge(maxAge * 24 * 60 * 60); cookie.setMaxAge(shiroProperties.getCookie().getMaxAge() * 24 * 60 * 60);
return cookie; return cookie;
} }

View File

@ -0,0 +1,76 @@
package com.ruoyi.framework.configuration;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author Charles
* @date 2018/11/13
* @desciption
*/
@Data
@Component
@ConfigurationProperties(prefix = "shiro")
public class ShiroProperties {
private User user;
private Cookie cookie;
private Session session;
private List<String> anon;
@Data
public static class User{
// 登录地址
private String loginUrl;
// 权限认证失败地址
private String unauthorizedUrl;
// 首页地址
private String indexUrl;
// 验证码开关
private boolean captchaEnabled;
// 验证码类型 math 数组计算 char 字符
private String captchaType;
}
@Data
public static class Cookie{
// 设置Cookie的域名 默认空即当前访问的域名
private String domain;
// 设置cookie的有效访问路径
private String path;
// 设置HttpOnly属性
private boolean httpOnly;
// 设置Cookie的过期时间天为单位
private int maxAge;
}
@Data
public static class Session {
// Session超时时间默认30分钟
private int expireTime;
// 同步session到数据库的周期默认1分钟
private int dbSyncPeriod;
// 相隔多久检查一次session的有效性默认就是10分钟
private int validationInterval;
}
}