Initial commit

This commit is contained in:
易焱
2019-07-30 18:14:32 +08:00
commit daa60cf523
1624 changed files with 90832 additions and 0 deletions
+44
View File
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cwhelp.component</groupId>
<artifactId>shiro</artifactId>
<packaging>jar</packaging>
<name>组件:Shiro权限</name>
<parent>
<groupId>com.cwhelp</groupId>
<artifactId>component</artifactId>
<version>2.0.1</version>
</parent>
<dependencies>
<dependency>
<groupId>com.cwhelp</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.cwhelp.modules</groupId>
<artifactId>system</artifactId>
<version>${project.version}</version>
</dependency>
<!--shiro权限管理框架-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>${shiro.version}</version>
</dependency>
</dependencies>
</project>
+133
View File
@@ -0,0 +1,133 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
<facet type="web" name="Web">
<configuration>
<webroots />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="common" />
<orderEntry type="module" module-name="system" />
<orderEntry type="module" module-name="excel" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:4.0.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:4.0.0" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.11" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:4.0.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:3.0.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.18" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.04" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-spring:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-lang:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-crypto-hash:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-crypto-core:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-crypto-cipher:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-config-core:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-config-ogdl:1.4.0" level="project" />
<orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.9.3" level="project" />
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-event:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-web:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-ehcache:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-cache:1.4.0" level="project" />
<orderEntry type="library" name="Maven: net.sf.ehcache:ehcache-core:2.6.11" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.11.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.11.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.26" level="project" />
<orderEntry type="library" name="Maven: javax.annotation:javax.annotation-api:1.3.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.yaml:snakeyaml:1.23" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.9.8" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.9.0" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.9.8" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.8" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.8" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.9.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.17" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.0.16.Final" level="project" />
<orderEntry type="library" name="Maven: javax.validation:validation-api:2.0.1.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.3.2.Final" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-jpa:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.2.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: javax.transaction:javax.transaction-api:1.3" level="project" />
<orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
<orderEntry type="library" name="Maven: org.hibernate:hibernate-core:5.3.9.Final" level="project" />
<orderEntry type="library" name="Maven: javax.persistence:javax.persistence-api:2.2" level="project" />
<orderEntry type="library" name="Maven: org.javassist:javassist:3.23.1-GA" level="project" />
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.9.12" level="project" />
<orderEntry type="library" name="Maven: antlr:antlr:2.7.7" level="project" />
<orderEntry type="library" name="Maven: org.jboss:jandex:2.0.5.Final" level="project" />
<orderEntry type="library" name="Maven: org.dom4j:dom4j:2.1.1" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.common:hibernate-commons-annotations:5.0.4.Final" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-jpa:2.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-orm:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aspects:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-configuration-processor:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.1.6.RELEASE" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.springframework.boot:spring-boot-devtools:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.1.4.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.1.4.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test:2.1.4.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:2.1.4.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.jayway.jsonpath:json-path:2.4.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:json-smart:2.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:accessors-smart:1.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm:5.0.4" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.assertj:assertj-core:3.11.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:2.23.4" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy-agent:1.9.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:2.6" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-library:1.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.5.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.1.6.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:5.1.6.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.xmlunit:xmlunit-core:2.6.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:5.1.46" level="project" />
<orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.2" level="project" />
<orderEntry type="library" name="Maven: net.sf.ehcache:ehcache:2.10.5" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.26" level="project" />
<orderEntry type="library" name="Maven: org.jsoup:jsoup:1.11.3" level="project" />
</component>
</module>
@@ -0,0 +1,109 @@
package com.cwhelp.component.shiro;
import com.cwhelp.common.constant.AdminConst;
import com.cwhelp.common.enums.StatusEnum;
import com.cwhelp.modules.system.domain.User;
import com.cwhelp.modules.system.service.RoleService;
import com.cwhelp.modules.system.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.codec.CodecSupport;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import javax.annotation.PostConstruct;
/**
* @author yan.y
*/
public class AuthRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
@Autowired
private RoleService roleService;
/**
* 授权逻辑
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// 获取用户Principal对象
User user = (User) principal.getPrimaryPrincipal();
// 管理员拥有所有权限
if(user.getId().equals(AdminConst.ADMIN_ID)){
info.addRole(AdminConst.ADMIN_ROLE_NAME);
info.addStringPermission("*:*:*");
return info;
}
// 获取角色和资源(JPA延迟加载超时,通过用户ID获取角色列表)
user.setRoles(roleService.getUserOkRoleList(user.getId()));
// 赋予角色和资源授权
user.getRoles().forEach(role -> {
info.addRole(role.getName());
role.getMenus().forEach(menu -> {
String perms = menu.getPerms();
if(menu.getStatus().equals(StatusEnum.OK.getCode())
&& !StringUtils.isEmpty(perms) && !perms.contains("*")){
info.addStringPermission(perms);
}
});
});
return info;
}
/**
* 认证逻辑
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
// 获取数据库中的用户名密码
User user = userService.getByName(token.getUsername());
// 判断用户名是否存在
if(user == null){
throw new UnknownAccountException();
}else if(user.getStatus().equals(StatusEnum.FREEZED.getCode())){
throw new LockedAccountException();
}
// 对盐进行加密处理
ByteSource salt = ByteSource.Util.bytes(user.getSalt());
/* 传入密码自动判断是否正确
* 参数1:传入对象给Principal
* 参数2:正确的用户密码
* 参数3:加盐处理
* 参数4:固定写法
*/
return new SimpleAuthenticationInfo(user, user.getPassword(), salt, getName());
}
/**
* 自定义密码验证匹配器
*/
@PostConstruct
public void initCredentialsMatcher() {
setCredentialsMatcher(new SimpleCredentialsMatcher() {
@Override
public boolean doCredentialsMatch(AuthenticationToken authenticationToken, AuthenticationInfo authenticationInfo) {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
SimpleAuthenticationInfo info = (SimpleAuthenticationInfo) authenticationInfo;
// 获取明文密码及密码盐
String password = String.valueOf(token.getPassword());
String salt = CodecSupport.toString(info.getCredentialsSalt().getBytes());
return equals(ShiroUtil.encrypt(password, salt), info.getCredentials());
}
});
}
}
@@ -0,0 +1,76 @@
package com.cwhelp.component.shiro;
import com.cwhelp.common.utils.EncryptUtil;
import com.cwhelp.common.utils.SpringContextUtil;
import com.cwhelp.modules.system.domain.Role;
import com.cwhelp.modules.system.domain.User;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.RememberMeManager;
import java.util.Set;
/**
* Shiro工具类
* @author yan.y
*/
public class ShiroUtil {
/**
* 加密算法
*/
public final static String hashAlgorithmName = EncryptUtil.hashAlgorithmName;
/**
* 循环次数
*/
public final static int hashIterations = EncryptUtil.hashIterations;
/**
* 加密处理
* 备注:采用自定义的密码加密方式,其原理与SimpleHash一致,
* 为的是在多个模块间可以使用同一套加密方式,方便共用系统用户。
* @param password 密码
* @param salt 密码盐
*/
public static String encrypt(String password, String salt) {
return EncryptUtil.encrypt(password, salt, hashAlgorithmName, hashIterations);
}
/**
* 获取随机盐值
*/
public static String getRandomSalt(){
return EncryptUtil.getRandomSalt();
}
/**
* 获取ShiroUser对象
*/
public static User getSubject(){
return (User) SecurityUtils.getSubject().getPrincipal();
}
/**
* 获取用户IP地址
*/
public static String getIp(){
return SecurityUtils.getSubject().getSession().getHost();
}
/**
* 重置Cookie“记住我”序列化信息
*/
public static void resetCookieRememberMe(){
Set<Role> roles = getSubject().getRoles();
getSubject().setRoles(null);
RememberMeManager meManager = SpringContextUtil.getBean(RememberMeManager.class);
UsernamePasswordToken token = new UsernamePasswordToken();
token.setRememberMe(true);
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo();
info.setPrincipals(SecurityUtils.getSubject().getPrincipals());
meManager.onSuccessfulLogin(SecurityUtils.getSubject(), token, info);
getSubject().setRoles(roles);
}
}
@@ -0,0 +1,40 @@
package com.cwhelp.component.shiro;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.http.HttpStatus;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 处理session超时问题拦截器
* @author yan.y
*/
public class UserAuthFilter extends AccessControlFilter {
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
if (isLoginRequest(request, response)) {
return true;
} else {
Subject subject = getSubject(request, response);
return subject.getPrincipal() != null;
}
}
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpRequest = WebUtils.toHttp(request);
HttpServletResponse httpResponse = WebUtils.toHttp(response);
if (httpRequest.getHeader("X-Requested-With") != null
&& httpRequest.getHeader("X-Requested-With").equalsIgnoreCase("XMLHttpRequest")) {
httpResponse.sendError(HttpStatus.UNAUTHORIZED.value());
} else {
redirectToLogin(request, response);
}
return false;
}
}
@@ -0,0 +1,23 @@
package com.cwhelp.component.shiro.config;
import com.cwhelp.modules.system.domain.User;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.AuditorAware;
import java.util.Optional;
/**
* 审核员自动赋值配置
* @author yan.y
*/
@Configuration
public class AuditorConfig implements AuditorAware<User> {
@Override
public Optional<User> getCurrentAuditor() {
Subject subject = SecurityUtils.getSubject();
User user = (User) subject.getPrincipal();
return Optional.ofNullable(user);
}
}
@@ -0,0 +1,151 @@
package com.cwhelp.component.shiro.config;
import com.cwhelp.component.shiro.AuthRealm;
import com.cwhelp.component.shiro.UserAuthFilter;
import com.cwhelp.component.shiro.config.properties.ShiroProjectProperties;
import net.sf.ehcache.CacheManager;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.codec.Base64;
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.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
/**
* @author yan.y
*/
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
/**
* 添加自定义拦截器,重写user认证方式,处理session超时问题
*/
HashMap<String, Filter> myFilters = new HashMap<>();
myFilters.put("userAuth", new UserAuthFilter());
shiroFilterFactoryBean.setFilters(myFilters);
/**
* 过滤规则(注意优先级)
* —anon 无需认证(登录)可访问
* —authc 必须认证才可访问
* —perms[标识] 拥有资源权限才可访问
* —role 拥有角色权限才可访问
* —user 认证和自动登录可访问
*/
LinkedHashMap<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/login", "anon");
filterMap.put("/logout", "anon");
filterMap.put("/captcha", "anon");
filterMap.put("/noAuth", "anon");
filterMap.put("/css/**", "anon");
filterMap.put("/js/**", "anon");
filterMap.put("/images/**", "anon");
filterMap.put("/lib/**", "anon");
filterMap.put("/favicon.ico", "anon");
filterMap.put("/**", "userAuth");
// 设置过滤规则
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
// 设置登录页面
shiroFilterFactoryBean.setLoginUrl("/login");
// 未授权错误页面
shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth");
return shiroFilterFactoryBean;
}
@Bean
public DefaultWebSecurityManager getDefaultWebSecurityManager(AuthRealm authRealm,
DefaultWebSessionManager sessionManager,
CookieRememberMeManager rememberMeManager) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(authRealm);
securityManager.setSessionManager(sessionManager);
securityManager.setRememberMeManager(rememberMeManager);
return securityManager;
}
/**
* 自定义的Realm
*/
@Bean
public AuthRealm getRealm(EhCacheManager ehCacheManager) {
AuthRealm authRealm = new AuthRealm();
authRealm.setCacheManager(ehCacheManager);
return authRealm;
}
/**
* 缓存管理器-使用Ehcache实现缓存
*/
@Bean
public EhCacheManager ehCacheManager(CacheManager cacheManager) {
EhCacheManager ehCacheManager = new EhCacheManager();
ehCacheManager.setCacheManager(cacheManager);
return ehCacheManager;
}
/**
* session管理器
*/
@Bean
public DefaultWebSessionManager getDefaultWebSessionManager(EhCacheManager cacheManager, ShiroProjectProperties properties) {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setCacheManager(cacheManager);
sessionManager.setGlobalSessionTimeout(properties.getGlobalSessionTimeout() * 1000);
sessionManager.setSessionValidationInterval(properties.getSessionValidationInterval() * 1000);
sessionManager.setDeleteInvalidSessions(true);
sessionManager.validateSessions();
// 去掉登录页面地址栏jsessionid
sessionManager.setSessionIdUrlRewritingEnabled(false);
return sessionManager;
}
/**
* rememberMe管理器
*/
@Bean
public CookieRememberMeManager rememberMeManager(SimpleCookie rememberMeCookie) {
CookieRememberMeManager manager = new CookieRememberMeManager();
manager.setCipherKey(Base64.decode("WcfHGU25gNnTxTlmJMeSpw=="));
manager.setCookie(rememberMeCookie);
return manager;
}
/**
* 创建一个简单的Cookie对象
*/
@Bean
public SimpleCookie rememberMeCookie(ShiroProjectProperties properties) {
SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
simpleCookie.setHttpOnly(true);
// cookie记住登录信息时间,默认7天
simpleCookie.setMaxAge(properties.getRememberMeTimeout() * 24 * 60 * 60);
return simpleCookie;
}
/**
* 启用shrio授权注解拦截方式,AOP式方法级权限检查
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor =
new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
}
@@ -0,0 +1,21 @@
package com.cwhelp.component.shiro.config.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 项目-shiro会话配置项
* @author yan.y
*/
@Data
@Component
@ConfigurationProperties(prefix = "project.shiro")
public class ShiroProjectProperties {
// cookie记住登录信息时间,默认7天
private Integer rememberMeTimeout = 7;
// Session会话超时时间,默认30分钟
private Integer globalSessionTimeout = 1800;
// Session会话检测间隔时间,默认15分钟
private Integer sessionValidationInterval = 900;
}
@@ -0,0 +1,52 @@
package com.cwhelp.component.shiro.exception;
import com.cwhelp.common.enums.ResultEnum;
import com.cwhelp.common.utils.ResultVoUtil;
import com.cwhelp.common.utils.SpringContextUtil;
import com.cwhelp.common.vo.ResultVo;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 拦截访问权限异常处理
* @author yan.y
*/
@ControllerAdvice
@Order(-1)
public class AuthorizationExceptionHandler {
// 拦截访问权限异常
@ExceptionHandler(AuthorizationException.class)
@ResponseBody
public ResultVo authorizationException(AuthorizationException e, HttpServletRequest request,
HttpServletResponse response){
Integer code = ResultEnum.NO_PERMISSIONS.getCode();
String msg = ResultEnum.NO_PERMISSIONS.getMessage();
// 获取异常信息
Throwable cause = e.getCause();
String message = cause.getMessage();
Class<ResultVo> resultVoClass = ResultVo.class;
// 判断无权限访问的方法返回对象是否为ResultVo
if(!message.contains(resultVoClass.getName())){
try {
// 重定向到无权限页面
String contextPath = request.getContextPath();
ShiroFilterFactoryBean shiroFilter = SpringContextUtil.getBean(ShiroFilterFactoryBean.class);
response.sendRedirect(contextPath+shiroFilter.getUnauthorizedUrl());
} catch (IOException e1) {
return ResultVoUtil.error(code, msg);
}
}
return ResultVoUtil.error(code, msg);
}
}
@@ -0,0 +1,30 @@
{
"groups": [
{
"name": "project.shiro",
"type": "com.cwhelp.component.shiro.config.properties.ShiroProjectProperties",
"sourceType": "com.cwhelp.component.shiro.config.properties.ShiroProjectProperties"
}
],
"properties": [
{
"name": "project.shiro.global-session-timeout",
"type": "java.lang.Integer",
"sourceType": "com.cwhelp.component.shiro.config.properties.ShiroProjectProperties",
"defaultValue": 1800
},
{
"name": "project.shiro.remember-me-timeout",
"type": "java.lang.Integer",
"sourceType": "com.cwhelp.component.shiro.config.properties.ShiroProjectProperties",
"defaultValue": 7
},
{
"name": "project.shiro.session-validation-interval",
"type": "java.lang.Integer",
"sourceType": "com.cwhelp.component.shiro.config.properties.ShiroProjectProperties",
"defaultValue": 900
}
],
"hints": []
}