Initial commit
This commit is contained in:
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
+21
@@ -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;
|
||||
}
|
||||
+52
@@ -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": []
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Reference in New Issue
Block a user