初始化git仓库

master
sunzhiqiang23 4 years ago
commit 058b66cb26

31
.gitignore vendored

@ -0,0 +1,31 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
### VS Code ###
.vscode/

@ -0,0 +1,195 @@
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bjmashibing.shiro</groupId>
<artifactId>shiro</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>shiro</name>
<description>Demo project for Spring Boot</description>
<modules>
<module>shiro-quickstart</module>
<module>shiro-springboot-basic</module>
<module>shiro-springboot-form</module>
<module>shiro-springboot-cluser-8001</module>
<module>shiro-springboot-cluser-8002</module>
<module>shiro-springboot-sso-server-9001</module>
<module>shiro-springboot-sso-client-taobao-9002</module>
<module>shiro-springboot-sso-client-tmail-9003</module>
<module>shiro-springboot-cas-server</module>
<module>shiro-springboot-cas-taobao-9004</module>
<module>shiro-springboot-cas-tmail-9005</module>
<module>shiro-springboot-cas-pac4j-taobao-9006</module>
<module>shiro-springboot-cas-pac4j-tmail-9007</module>
<module>shiro-springboot-jwt-9008</module>
<module>shiro-springboot-cas-pac4j-admin-9008</module>
<module>shiro-springboot-admin-9010</module>
</modules>
<properties>
<java.version>1.8</java.version>
<shiro.version>1.4.1</shiro.version>
<mysql.version>5.1.38</mysql.version>
<mybatis.plus.version>3.3.1</mybatis.plus.version>
<druid.version>1.1.9</druid.version>
<lombok.version>1.18.10</lombok.version>
<kaptcha.version>0.0.9</kaptcha.version>
<fastjson.version>1.2.67</fastjson.version>
<commons.lang3.version>3.9</commons.lang3.version>
<java.jwt.version>3.2.0</java.jwt.version>
<joda.time.version>2.9.9</joda.time.version>
<pagehelper.version>1.2.5</pagehelper.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.2.6.RELEASE</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--shiro 核心-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiro.version}</version>
</dependency>
<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>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-cas</artifactId>
<version>${shiro.version}</version>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis.plus.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>${mybatis.plus.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>com.github.axet</groupId>
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons.lang3.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.mingsoft/shiro-freemarker-tags -->
<dependency>
<groupId>net.mingsoft</groupId>
<artifactId>shiro-freemarker-tags</artifactId>
<version>1.0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>${java.jwt.version}</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${joda.time.version}</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,55 @@
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.bjmashibing.shiro</groupId>
<artifactId>shiro</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bjmashibing.shiro</groupId>
<artifactId>shiro-quickstart</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>shiro-quickstart</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--shiro 核心-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,45 @@
package com.bjmashibing.shiro;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
/**
* <p></p>
*
* @author sunzhiqiang23
* @date 2020-04-08 21:09
*/
public class CryptoRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//连接数据库
String username = "admin";
String password = "c657540d5b315892f950ff30e1394480";
String salt = "salt";
return new SimpleAuthenticationInfo(username, password, ByteSource.Util.bytes(salt), getName());
}
@Override
public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
HashedCredentialsMatcher shaCredentialsMatcher = new HashedCredentialsMatcher();
shaCredentialsMatcher.setHashAlgorithmName("MD5");
shaCredentialsMatcher.setHashIterations(1);
shaCredentialsMatcher.setStoredCredentialsHexEncoded(true);
super.setCredentialsMatcher(shaCredentialsMatcher);
}
}

@ -0,0 +1,43 @@
package com.bjmashibing.shiro;
import org.apache.shiro.authc.*;
import org.apache.shiro.realm.Realm;
/**
* <p></p>
*
* @author sunzhiqiang23
* @date 2020-04-08 21:09
*/
public class MyRealm1 implements Realm {
// 注入用户service
@Override
public String getName() {
return "myRealm1";
}
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof UsernamePasswordToken;
}
@Override
public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//得到用户名
String username = (String)token.getPrincipal();
//得到密码
String password = new String((char[])token.getCredentials());
//如果用户名错误
if(!"system".equals(username)) {
throw new UnknownAccountException();
}
//如果密码错误
if(!"system".equals(password)) {
throw new IncorrectCredentialsException();
}
//如果身份认证验证成功返回一个AuthenticationInfo实现
return new SimpleAuthenticationInfo(username, password, getName());
}
}

@ -0,0 +1,40 @@
package com.bjmashibing.shiro;
import org.apache.shiro.authc.*;
import org.apache.shiro.realm.Realm;
/**
* <p></p>
*
* @author sunzhiqiang23
* @date 2020-04-08 21:09
*/
public class MyRealm2 implements Realm {
@Override
public String getName() {
return "myRealm2";
}
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof UsernamePasswordToken;
}
@Override
public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//得到用户名
String username = (String)token.getPrincipal();
//得到密码
String password = new String((char[])token.getCredentials());
//如果用户名错误
if(!"admin".equals(username)) {
throw new UnknownAccountException();
}
//如果密码错误
if(!"admin".equals(password)) {
throw new IncorrectCredentialsException();
}
//如果身份认证验证成功返回一个AuthenticationInfo实现
return new SimpleAuthenticationInfo(username, password, getName());
}
}

@ -0,0 +1,40 @@
package com.bjmashibing.shiro;
import org.apache.shiro.authc.*;
import org.apache.shiro.realm.Realm;
/**
* <p></p>
*
* @author sunzhiqiang23
* @date 2020-04-08 21:09
*/
public class MyRealm3 implements Realm {
@Override
public String getName() {
return "myRealm3";
}
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof UsernamePasswordToken;
}
@Override
public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//得到用户名
String username = (String)token.getPrincipal();
//得到密码
String password = new String((char[])token.getCredentials());
//如果用户名错误
if(!"zhangsan".equals(username)) {
throw new UnknownAccountException();
}
//如果密码错误
if(!"zhangsan".equals(password)) {
throw new IncorrectCredentialsException();
}
//如果身份认证验证成功返回一个AuthenticationInfo实现
return new SimpleAuthenticationInfo(username, password, getName());
}
}

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Logback configuration. See http://logback.qos.ch/manual/index.html -->
<configuration scan="true" scanPeriod="10 seconds">
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%date [%level] [%thread] %logger{60} [%file : %line] %msg%n</pattern>
</encoder>
</appender>
<!--指定最基础的日志输出级别-->
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>

@ -0,0 +1,9 @@
[users]
system = system, user
admin = admin, admin
zhangsan = zhangsan ,user
[roles]
system = *
admin = user:*
user = user:insert

@ -0,0 +1,187 @@
package test;
import com.bjmashibing.shiro.CryptoRealm;
import com.bjmashibing.shiro.MyRealm1;
import com.bjmashibing.shiro.MyRealm2;
import com.bjmashibing.shiro.MyRealm3;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.pam.FirstSuccessfulStrategy;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
/**
* <p></p>
*
* @author sunzhiqiang23
* @date 2020-04-07 11:45
*/
@Slf4j
public class LoginShiro {
/**
*
*/
@Test
public void testBasicLogin() throws InterruptedException {
DefaultSecurityManager securityManager=new DefaultSecurityManager();
IniRealm iniRealm=new IniRealm("classpath:shiro-quick-start.ini");
securityManager.setRealm(iniRealm);
SecurityUtils.setSecurityManager(securityManager);
// 1-获取当前用户信息
Subject currentUser = SecurityUtils.getSubject();
Session session = currentUser.getSession();
session.setAttribute("key", "value");
String key = (String) session.getAttribute("key");
System.out.println("key 值:" + key);
// 2-当前用户登陆
if (!currentUser.isAuthenticated()) {
UsernamePasswordToken token = new UsernamePasswordToken("system", "system");
try {
currentUser.login(token);
new Thread(() -> {
System.out.println("登陆成功,登录用户"+SecurityUtils.getSubject().getPrincipals());
}).start();
} catch (UnknownAccountException uae) {
log.info("无此用户,用户名: " + token.getPrincipal());
} catch (IncorrectCredentialsException ice) {
log.info("密码不正确 " + token.getPrincipal() + " was incorrect!");
}
}
new CountDownLatch(1).await();
//3-退出
// currentUser.logout();
// System.exit(0);
}
/**
* realm
*/
@Test
public void testOneRealms(){
DefaultSecurityManager securityManager=new DefaultSecurityManager();
securityManager.setRealm(new MyRealm1());
SecurityUtils.setSecurityManager(securityManager);
// 1-获取当前用户信息
Subject currentUser = SecurityUtils.getSubject();
// 2-当前用户登陆
if (!currentUser.isAuthenticated()) {
UsernamePasswordToken token = new UsernamePasswordToken("system", "system");
try {
currentUser.login(token);
log.info("登陆成功");
} catch (UnknownAccountException uae) {
log.info("无此用户,用户名: " + token.getPrincipal());
} catch (IncorrectCredentialsException ice) {
log.info("密码不正确 " + token.getPrincipal() + " was incorrect!");
}
}
//3-退出
currentUser.logout();
System.exit(0);
}
/**
* realm
*/
@Test
public void testMultiRealms(){
DefaultSecurityManager securityManager=new DefaultSecurityManager();
List<Realm> list = new ArrayList<>();
MyRealm1 myRealm1 = new MyRealm1();
MyRealm2 myRealm2 = new MyRealm2();
list.add(myRealm1);
list.add(myRealm2);
securityManager.setRealms(list);
SecurityUtils.setSecurityManager(securityManager);
// 1-获取当前用户信息
Subject currentUser = SecurityUtils.getSubject();
// 2-当前用户登陆
if (!currentUser.isAuthenticated()) {
UsernamePasswordToken token = new UsernamePasswordToken("system", "system");
try {
currentUser.login(token);
log.info("登陆成功");
} catch (UnknownAccountException uae) {
log.info("无此用户,用户名: " + token.getPrincipal());
} catch (IncorrectCredentialsException ice) {
log.info("密码不正确 " + token.getPrincipal() + " was incorrect!");
}
}
//3-退出
currentUser.logout();
System.exit(0);
}
/**
* realm
*/
@Test
public void testMultiRealmsStrate(){
DefaultSecurityManager securityManager=new DefaultSecurityManager();
List<Realm> list = new ArrayList<>();
list.add(new MyRealm1());
list.add(new MyRealm2());
list.add(new MyRealm3());
// 设置策略
ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
authenticator.setAuthenticationStrategy(new FirstSuccessfulStrategy());
// authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
// authenticator.setAuthenticationStrategy(new AllSuccessfulStrategy());
authenticator.setRealms(list);
securityManager.setAuthenticator(authenticator);
SecurityUtils.setSecurityManager(securityManager);
// 1-获取当前用户信息
Subject currentUser = SecurityUtils.getSubject();
// 2-当前用户登陆
if (!currentUser.isAuthenticated()) {
UsernamePasswordToken token = new UsernamePasswordToken("system", "system1");
try {
currentUser.login(token);
PrincipalCollection principals = currentUser.getPrincipals();
log.info("登陆成功:"+principals);
} catch (UnknownAccountException uae) {
log.info("无此用户,用户名: " + token.getPrincipal());
} catch (IncorrectCredentialsException ice) {
log.info("密码不正确 " + token.getPrincipal() + " was incorrect!");
}
}
//3-退出
currentUser.logout();
System.exit(0);
}
/**
*
*/
@Test
public void testCrypto() {
DefaultSecurityManager securityManager = new DefaultSecurityManager();
securityManager.setRealm(new CryptoRealm());
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("admin", "admin1");
subject.login(token);
boolean authenticated = subject.isAuthenticated();
if (authenticated) {
System.out.println("登陆成功");
}
}
}

@ -0,0 +1,31 @@
package test;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.junit.jupiter.api.Test;
/**
* <p></p>
*
* @author sunzhiqiang23
* @date 2020-04-25 11:44
*/
public class MD5Test {
@Test
public void testMD5(){
String password = "admin";
String salt = "salt";
String result = new Md5Hash(password, salt, 1).toString();
//c657540d5b315892f950ff30e1394480
System.out.println(result);
}
@Test
public void testSimpleHash() {
String password = "admin";
String salt = "salt";
SimpleHash simpleHash = new SimpleHash("MD5", password, salt, 1);
//c657540d5b315892f950ff30e1394480
System.out.println(simpleHash.toString());
}
}

@ -0,0 +1,74 @@
package test;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.junit.jupiter.api.Test;
/**
* <p>--session退</p>
*
* @author sunzhiqiang23
* @date 2020-04-07 11:45
*/
@Slf4j
public class QuickStartShiro {
@Test
public void test(){
//1-初始化环境
DefaultSecurityManager securityManager=new DefaultSecurityManager();
IniRealm iniRealm=new IniRealm("classpath:shiro-quick-start.ini");
securityManager.setRealm(iniRealm);
//绑定当前 securityManager
SecurityUtils.setSecurityManager(securityManager);
// 2--获取当前用户信息
Subject subject = SecurityUtils.getSubject();
// 3-当前用户信息 操作一些事情--不需要web环境和其他容器支持
Session session = subject.getSession();
session.setAttribute("someKey", "value");
String value = (String) session.getAttribute("someKey");
if (value.equals("value")) {
log.info("检测到 正确的 value 值! [" + value + "]");
}
// 4-当前用户登陆,检查角色和权限
if (!subject.isAuthenticated()) {
UsernamePasswordToken token = new UsernamePasswordToken("system", "system");
token.setRememberMe(true);
try {
subject.login(token);
} catch (UnknownAccountException uae) {
log.info("无此用户,用户名: " + token.getPrincipal());
} catch (IncorrectCredentialsException ice) {
log.info("用户 " + token.getPrincipal() + " 登录密码不正确!");
} catch (LockedAccountException lae) {
log.info("用户名 " + token.getPrincipal() + " 被锁定.请联系管理员已解锁.");
}
// ... 系统自己定义的异常,系统提供了很多预制的异常,均 继承自 ShiroException或者起子类
catch (AuthenticationException ae) {
//unexpected condition? error?
}
}
//5 -验证
log.info("用户 [" + subject.getPrincipal() + "] 登陆成功.");
//6-测试角色
if (subject.hasRole("system")) {
log.info("拥有【system】角色!");
} else {
log.info("未拥有【system】角色!");
}
//5-测试权限码
if (subject.isPermitted("user:update")) {
log.info("拥有【user:update】权限.");
} else {
log.info("未拥有【user:update】权限..");
}
//6-退出
subject.logout();
System.exit(0);
}
}

@ -0,0 +1,49 @@
package test;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.session.mgt.DefaultSessionManager;
import org.apache.shiro.subject.Subject;
import org.junit.jupiter.api.Test;
/**
* <p></p>
*
* @author sunzhiqiang23
* @date 2020-04-25 20:10
*/
public class TestShiro {
@Test
public void testLogin() {
DefaultSecurityManager securityManager = new DefaultSecurityManager();
IniRealm realm = new IniRealm("classpath:shiro-quick-start.ini");
securityManager.setRealm(realm);
//绑定securityManager
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("system1", "system");
//密码不对 IncorrectCredentialsException 异常
//用户名不对UnknownAccountException 异常
subject.login(token);
if (subject.isAuthenticated()) {
System.out.println("登陆成功,登录用户" + subject.getPrincipal());
}else{
System.out.println("未登录");
}
subject.logout();
if (subject.isAuthenticated()) {
System.out.println("登陆成功,登录用户" + subject.getPrincipal());
}else{
System.out.println("未登录");
}
}
}

@ -0,0 +1,123 @@
<?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">
<parent>
<artifactId>shiro</artifactId>
<groupId>com.bjmashibing.shiro</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>shiro-springboot-admin-9010</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--shiro 核心-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.github.axet</groupId>
<artifactId>kaptcha</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>net.mingsoft</groupId>
<artifactId>shiro-freemarker-tags</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- 跳过单元测试 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<!-- put your configurations here -->
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,22 @@
package com.bjmashibing.shiro;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/**
* @author sunzhiqiang23
*/
@MapperScan(basePackages = {"com.bjmashibing.shiro.moduler.*.mapper"})
@SpringBootApplication
public class AdminApplication9010 extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(AdminApplication9010.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(AdminApplication9010.class);
}
}

@ -0,0 +1,47 @@
package com.bjmashibing.shiro.framework.util;
import java.util.HashMap;
/**
*
*
* @author
* @date 20191219 4:59:27
*/
public class R extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
public R() {
put("code", 0);
}
public static R error() {
return error(500, "未知异常,请联系管理员");
}
public static R error(String info) {
return error(500, info);
}
public static R error(int code, String info) {
R r = new R();
r.put("code", code);
r.put("info", info);
return r;
}
public static R ok(String info) {
R r = new R();
r.put("info", info);
return r;
}
public static R ok() {
return new R();
}
@Override
public R put(String key, Object value) {
super.put(key, value);
return this;
}
}

@ -0,0 +1,21 @@
package com.bjmashibing.shiro.init;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationFailedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/**
* <p></p>
*
* @author sunzhiqiang23
* @date 2020-03-31 13:57
*/
@Component
@Slf4j
public class ApplicationFailedEventListener implements ApplicationListener<ApplicationFailedEvent> {
@Override
public void onApplicationEvent(ApplicationFailedEvent event) {
log.info("系统启动失败......");
}
}

@ -0,0 +1,21 @@
package com.bjmashibing.shiro.init;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/**
* <p></p>
*
* @author sunzhiqiang23
* @date 2020-03-31 13:56
*/
@Component
@Slf4j
public class ApplicationReadyEventListene implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
log.info("系统启动成功......");
}
}

@ -0,0 +1,26 @@
package com.bjmashibing.shiro.moduler.system.controller;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import java.io.Serializable;
import java.util.Collection;
/**
* <p>
*
* </p>
*
* @author
* @since 2020-04-13
*/
@RestController
public class UserController {
}

@ -0,0 +1,67 @@
/**
*
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.bjmashibing.shiro.moduler.system.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.util.Date;
/**
*
* @author liuzp
* @since 2.0.0 2018-02-10
*/
@TableName("sys_captcha")
public class Captcha {
@TableId(type = IdType.INPUT)
private String uuid;
/**
*
*/
private String code;
/**
*
*/
private Date expireTime;
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Date getExpireTime() {
return expireTime;
}
public void setExpireTime(Date expireTime) {
this.expireTime = expireTime;
}
}

@ -0,0 +1,62 @@
/**
*
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.bjmashibing.shiro.moduler.system.entity;
/**
*
*
* @author liuzp
* @since 2.0.0 2018-01-25
*/
public class LoginForm {
private String username;
private String password;
private String captcha;
private String uuid;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getCaptcha() {
return captcha;
}
public void setCaptcha(String captcha) {
this.captcha = captcha;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
}

@ -0,0 +1,32 @@
/**
*
*/
package com.bjmashibing.shiro.moduler.system.entity;
import java.util.List;
/**
* <b></b> <br>
* <b></b><br>
* <b></b>2017531 11:37:57
* @version 1.0 <br>
*/
public class MenuData {
private List<Module> authorizeMenu ;
/**
* @return the authorizeMenu
*/
public List<Module> getAuthorizeMenu() {
return authorizeMenu;
}
/**
* @param authorizeMenu the authorizeMenu to set
*/
public void setAuthorizeMenu(List<Module> authorizeMenu) {
this.authorizeMenu = authorizeMenu;
}
}

@ -0,0 +1,93 @@
package com.bjmashibing.shiro.moduler.system.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
*
* </p>
*
* @author
* @since 2020-04-13
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("sys_module")
public class Module implements Serializable {
private static final long serialVersionUID = 1L;
/**
*
*/
private Long id;
/**
*
*/
private Long parentId;
/**
*
*/
private String code;
/**
*
*/
private String name;
/**
*
*/
private String icon;
/**
* :1-2-3-4-
*/
private Boolean type;
/**
* url
*/
private String url;
/**
* :01
*/
private Boolean isDelete;
/**
*
*/
private Date createTime;
/**
*
*/
private String createUserId;
/**
*
*/
private Date updateTime;
/**
*
*/
private String updateUser;
/**
*
*/
private Date ts;
}

@ -0,0 +1,78 @@
package com.bjmashibing.shiro.moduler.system.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
*
* </p>
*
* @author
* @since 2020-04-13
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("sys_role")
public class Role implements Serializable {
private static final long serialVersionUID = 1L;
/**
*
*/
private Long id;
/**
*
*/
private String code;
/**
*
*/
private String name;
/**
* :01
*/
private Boolean isDelete;
/**
*
*/
private String mark;
/**
*
*/
private Date createTime;
/**
*
*/
private String createUser;
/**
*
*/
private Date updateTime;
/**
*
*/
private String updateUser;
/**
*
*/
private Date ts;
}

@ -0,0 +1,42 @@
package com.bjmashibing.shiro.moduler.system.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* <p>
*
* </p>
*
* @author
* @since 2020-04-13
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("sys_role_module_ref")
public class RoleModuleRef implements Serializable {
private static final long serialVersionUID = 1L;
/**
*
*/
private Long id;
/**
*
*/
private Long module_id;
/**
*
*/
private Long roleId;
}

@ -0,0 +1,88 @@
package com.bjmashibing.shiro.moduler.system.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
*
* </p>
*
* @author
* @since 2020-04-13
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("sys_user")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
/**
*
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
*
*/
private String username;
/**
*
*/
private String password;
/**
*
*/
private String secretkey;
private Integer locked;
/**
*
*/
private String realName;
/**
* :01
*/
private Integer isDelete;
/**
*
*/
private Date createTime;
/**
*
*/
private String createUser;
/**
*
*/
private Date updateUser;
/**
*
*/
private Date updateTime;
/**
*
*/
private Date ts;
}

@ -0,0 +1,42 @@
package com.bjmashibing.shiro.moduler.system.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* <p>
*
* </p>
*
* @author
* @since 2020-04-13
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("sys_user_role_ref")
public class UserRoleRef implements Serializable {
private static final long serialVersionUID = 1L;
/**
*
*/
private Long id;
/**
*
*/
private Long userId;
/**
*
*/
private Long roleId;
}

@ -0,0 +1,77 @@
package com.bjmashibing.shiro.moduler.system.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
/**
* Token
*/
@TableName("sys_user_token")
public class UserToken implements Serializable {
private static final long serialVersionUID = 1L;
//用户ID
@TableId(type = IdType.INPUT)
private Long userId;
//token
private String token;
//过期时间
private Date expireTime;
//更新时间
private Date updateTime;
/**
* ID
*/
public void setUserId(Long userId) {
this.userId = userId;
}
/**
* ID
*/
public Long getUserId() {
return userId;
}
/**
* token
*/
public void setToken(String token) {
this.token = token;
}
/**
* token
*/
public String getToken() {
return token;
}
/**
*
*/
public void setExpireTime(Date expireTime) {
this.expireTime = expireTime;
}
/**
*
*/
public Date getExpireTime() {
return expireTime;
}
/**
*
*/
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
/**
*
*/
public Date getUpdateTime() {
return updateTime;
}
}

@ -0,0 +1,16 @@
package com.bjmashibing.shiro.moduler.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bjmashibing.shiro.moduler.system.entity.Captcha;
import org.apache.ibatis.annotations.Mapper;
/**
*
*
* @author liuzp
* @since 3.1.0 2018-02-10
*/
@Mapper
public interface CaptchaMapper extends BaseMapper<Captcha> {
}

@ -0,0 +1,16 @@
package com.bjmashibing.shiro.moduler.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bjmashibing.shiro.moduler.system.entity.Module;
/**
* <p>
* Mapper
* </p>
*
* @author
* @since 2020-04-13
*/
public interface ModuleMapper extends BaseMapper<Module> {
}

@ -0,0 +1,16 @@
package com.bjmashibing.shiro.moduler.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bjmashibing.shiro.moduler.system.entity.Role;
/**
* <p>
* Mapper
* </p>
*
* @author
* @since 2020-04-13
*/
public interface RoleMapper extends BaseMapper<Role> {
}

@ -0,0 +1,16 @@
package com.bjmashibing.shiro.moduler.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bjmashibing.shiro.moduler.system.entity.RoleModuleRef;
/**
* <p>
* Mapper
* </p>
*
* @author
* @since 2020-04-13
*/
public interface RoleModuleRefMapper extends BaseMapper<RoleModuleRef> {
}

@ -0,0 +1,21 @@
package com.bjmashibing.shiro.moduler.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bjmashibing.shiro.moduler.system.entity.Module;
import com.bjmashibing.shiro.moduler.system.entity.User;
import java.util.List;
/**
* <p>
* Mapper
* </p>
*
* @author
* @since 2020-04-13
*/
public interface UserMapper extends BaseMapper<User> {
List<String> getRoleCodeList(Long userId);
List<String> queryAllPerms(Long userId);
List<Module> findMenuListByUserId(Long userId);
}

@ -0,0 +1,16 @@
package com.bjmashibing.shiro.moduler.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bjmashibing.shiro.moduler.system.entity.UserRoleRef;
/**
* <p>
* Mapper
* </p>
*
* @author
* @since 2020-04-13
*/
public interface UserRoleRefMapper extends BaseMapper<UserRoleRef> {
}

@ -0,0 +1,19 @@
package com.bjmashibing.shiro.moduler.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bjmashibing.shiro.moduler.system.entity.UserToken;
import org.apache.ibatis.annotations.Mapper;
/**
* Token
*
* @author liuzp
* @email liuzp6@163.com
* @date 2017-03-23 15:22:07
*/
@Mapper
public interface UserTokenMapper extends BaseMapper<UserToken> {
UserToken queryByToken(String token);
}

@ -0,0 +1,30 @@
package com.bjmashibing.shiro.moduler.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bjmashibing.shiro.moduler.system.entity.Captcha;
import java.awt.image.BufferedImage;
/**
*
*
* @author liuzp
* @since 2.0.0 2018-02-10
*/
public interface CaptchaService extends IService<Captcha> {
/**
*
*/
BufferedImage getCaptcha(String uuid);
/**
*
* @param uuid uuid
* @param code
* @return true false
*/
boolean validate(String uuid, String code);
}

@ -0,0 +1,16 @@
package com.bjmashibing.shiro.moduler.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bjmashibing.shiro.moduler.system.entity.Module;
/**
* <p>
*
* </p>
*
* @author
* @since 2020-04-13
*/
public interface ModuleService extends IService<Module> {
}

@ -0,0 +1,16 @@
package com.bjmashibing.shiro.moduler.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bjmashibing.shiro.moduler.system.entity.RoleModuleRef;
/**
* <p>
*
* </p>
*
* @author
* @since 2020-04-13
*/
public interface RoleModuleRefService extends IService<RoleModuleRef> {
}

@ -0,0 +1,16 @@
package com.bjmashibing.shiro.moduler.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bjmashibing.shiro.moduler.system.entity.Role;
/**
* <p>
*
* </p>
*
* @author
* @since 2020-04-13
*/
public interface RoleService extends IService<Role> {
}

@ -0,0 +1,29 @@
package com.bjmashibing.shiro.moduler.system.service;
import com.bjmashibing.shiro.moduler.system.entity.UserToken;
import com.bjmashibing.shiro.moduler.system.entity.User;
import java.util.List;
import java.util.Set;
/**
* shiro
* @author liuzp
* @email liuzp6@163.com
* @date 2017-06-06 8:49
*/
public interface ShiroService {
/**
*
*/
List<String> getUserPermissions(long userId);
UserToken queryByToken(String token);
/**
* ID
* @param userId
*/
User queryUser(Long userId);
}

@ -0,0 +1,16 @@
package com.bjmashibing.shiro.moduler.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bjmashibing.shiro.moduler.system.entity.UserRoleRef;
/**
* <p>
*
* </p>
*
* @author
* @since 2020-04-13
*/
public interface UserRoleRefService extends IService<UserRoleRef> {
}

@ -0,0 +1,24 @@
package com.bjmashibing.shiro.moduler.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bjmashibing.shiro.moduler.system.entity.Module;
import com.bjmashibing.shiro.moduler.system.entity.User;
import java.util.List;
/**
* <p>
*
* </p>
*
* @author
* @since 2020-04-13
*/
public interface UserService extends IService<User> {
User queryByUserName(String username);
List<String> getRoleCodeList(Long userId);
List<String> queryAllPerms(Long userId);
List<Module> findMenuListByUserId(Long userId);
}

@ -0,0 +1,28 @@
package com.bjmashibing.shiro.moduler.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bjmashibing.shiro.framework.util.R;
import com.bjmashibing.shiro.moduler.system.entity.UserToken;
/**
* Token
*
* @author liuzp
* @date 2017-03-23 15:22:07
*/
public interface UserTokenService extends IService<UserToken> {
/**
* token
* @param userId ID
*/
R createToken(long userId);
/**
* 退token
* @param userId ID
*/
void logout(long userId);
}

@ -0,0 +1,62 @@
package com.bjmashibing.shiro.moduler.system.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bjmashibing.shiro.moduler.system.entity.Captcha;
import com.bjmashibing.shiro.moduler.system.mapper.CaptchaMapper;
import com.bjmashibing.shiro.moduler.system.service.CaptchaService;
import com.google.code.kaptcha.Producer;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.awt.image.BufferedImage;
import java.util.Date;
/**
*
*
* @author liuzp
* @since 2.0.0 2018-02-10
*/
@Service("captchaService")
public class CaptchaServiceImpl extends ServiceImpl<CaptchaMapper, Captcha> implements CaptchaService {
@Autowired
private Producer producer;
@Override
public BufferedImage getCaptcha(String uuid) {
if(StringUtils.isBlank(uuid)){
throw new RuntimeException("uuid不能为空");
}
//生成文字验证码
String code = producer.createText();
Captcha captchaEntity = new Captcha();
captchaEntity.setUuid(uuid);
captchaEntity.setCode(code);
this.save(captchaEntity);
return producer.createImage(code);
}
@Override
public boolean validate(String uuid, String code) {
LambdaQueryWrapper<Captcha> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Captcha::getUuid, uuid);
Captcha captchaEntity = this.getOne(wrapper);
if(captchaEntity == null){
return false;
}
//删除验证码
this.removeById(uuid);
if(captchaEntity.getCode().equalsIgnoreCase(code)){
return true;
}
return false;
}
}

@ -0,0 +1,20 @@
package com.bjmashibing.shiro.moduler.system.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bjmashibing.shiro.moduler.system.entity.Module;
import com.bjmashibing.shiro.moduler.system.mapper.ModuleMapper;
import com.bjmashibing.shiro.moduler.system.service.ModuleService;
import org.springframework.stereotype.Service;
/**
* <p>
*
* </p>
*
* @author
* @since 2020-04-13
*/
@Service
public class ModuleServiceImpl extends ServiceImpl<ModuleMapper, Module> implements ModuleService {
}

@ -0,0 +1,20 @@
package com.bjmashibing.shiro.moduler.system.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bjmashibing.shiro.moduler.system.entity.RoleModuleRef;
import com.bjmashibing.shiro.moduler.system.mapper.RoleModuleRefMapper;
import com.bjmashibing.shiro.moduler.system.service.RoleModuleRefService;
import org.springframework.stereotype.Service;
/**
* <p>
*
* </p>
*
* @author
* @since 2020-04-13
*/
@Service
public class RoleModuleRefServiceImpl extends ServiceImpl<RoleModuleRefMapper, RoleModuleRef> implements RoleModuleRefService {
}

@ -0,0 +1,20 @@
package com.bjmashibing.shiro.moduler.system.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bjmashibing.shiro.moduler.system.entity.Role;
import com.bjmashibing.shiro.moduler.system.mapper.RoleMapper;
import com.bjmashibing.shiro.moduler.system.service.RoleService;
import org.springframework.stereotype.Service;
/**
* <p>
*
* </p>
*
* @author
* @since 2020-04-13
*/
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
}

@ -0,0 +1,39 @@
package com.bjmashibing.shiro.moduler.system.service.impl;
import com.bjmashibing.shiro.moduler.system.entity.User;
import com.bjmashibing.shiro.moduler.system.entity.UserToken;
import com.bjmashibing.shiro.moduler.system.mapper.UserMapper;
import com.bjmashibing.shiro.moduler.system.mapper.UserTokenMapper;
import com.bjmashibing.shiro.moduler.system.service.ShiroService;
import com.bjmashibing.shiro.moduler.system.service.UserService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
@Service
public class ShiroServiceImpl implements ShiroService {
@Autowired
private UserService userService;
@Autowired
private UserMapper userMapper;
@Autowired
private UserTokenMapper userTokenMapper;
@Override
public List<String> getUserPermissions(long userId) {
List<String> permsList = userService.queryAllPerms(userId);
return permsList;
}
@Override
public UserToken queryByToken(String token) {
return userTokenMapper.queryByToken(token);
}
@Override
public User queryUser(Long userId) {
return userMapper.selectById(userId);
}
}

@ -0,0 +1,20 @@
package com.bjmashibing.shiro.moduler.system.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bjmashibing.shiro.moduler.system.entity.UserRoleRef;
import com.bjmashibing.shiro.moduler.system.mapper.UserRoleRefMapper;
import com.bjmashibing.shiro.moduler.system.service.UserRoleRefService;
import org.springframework.stereotype.Service;
/**
* <p>
*
* </p>
*
* @author
* @since 2020-04-13
*/
@Service
public class UserRoleRefServiceImpl extends ServiceImpl<UserRoleRefMapper, UserRoleRef> implements UserRoleRefService {
}

@ -0,0 +1,42 @@
package com.bjmashibing.shiro.moduler.system.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bjmashibing.shiro.moduler.system.entity.Module;
import com.bjmashibing.shiro.moduler.system.entity.User;
import com.bjmashibing.shiro.moduler.system.mapper.UserMapper;
import com.bjmashibing.shiro.moduler.system.service.UserService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* <p>
*
* </p>
*
* @author
* @since 2020-04-13
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Override
public User queryByUserName(String username) {
return this.getOne(new QueryWrapper<User>().eq("username", username));
}
@Override
public List<String> getRoleCodeList(Long userId) {
return baseMapper.getRoleCodeList(userId);
}
@Override
public List<String> queryAllPerms(Long userId) {
return baseMapper.queryAllPerms(userId);
}
@Override
public List<Module> findMenuListByUserId(Long userId) {
return baseMapper.findMenuListByUserId(userId);
}
}

@ -0,0 +1,66 @@
package com.bjmashibing.shiro.moduler.system.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bjmashibing.shiro.framework.util.R;
import com.bjmashibing.shiro.moduler.system.entity.UserToken;
import com.bjmashibing.shiro.moduler.system.mapper.UserTokenMapper;
import com.bjmashibing.shiro.moduler.system.service.UserTokenService;
import com.bjmashibing.shiro.shiro.TokenGenerator;
import org.springframework.stereotype.Service;
import java.util.Date;
@Service("sysUserTokenService")
public class UserTokenServiceImpl extends ServiceImpl<UserTokenMapper, UserToken> implements UserTokenService {
//12小时后过期
private final static int EXPIRE = 3600 * 12;
@Override
public R createToken(long userId) {
//生成一个token
String token = TokenGenerator.generateValue();
//当前时间
Date now = new Date();
//过期时间
Date expireTime = new Date(now.getTime() + EXPIRE * 1000);
//判断是否生成过token
UserToken tokenEntity = this.getById(userId);
if(tokenEntity == null){
tokenEntity = new UserToken();
tokenEntity.setUserId(userId);
tokenEntity.setToken(token);
tokenEntity.setUpdateTime(now);
tokenEntity.setExpireTime(expireTime);
//保存token
this.save(tokenEntity);
}else{
tokenEntity.setToken(token);
tokenEntity.setUpdateTime(now);
tokenEntity.setExpireTime(expireTime);
//更新token
this.updateById(tokenEntity);
}
R r = R.ok().put("token", token).put("expire", EXPIRE);
return r;
}
@Override
public void logout(long userId) {
//生成一个token
String token = TokenGenerator.generateValue();
//修改token
UserToken tokenEntity = new UserToken();
tokenEntity.setUserId(userId);
tokenEntity.setToken(token);
this.updateById(tokenEntity);
}
}

@ -0,0 +1,34 @@
package com.bjmashibing.shiro.shiro;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
/**
*
*
* @author
* @date 2017-04-20 19:22
*/
@Configuration
public class KaptchaConfig {
@Bean
public DefaultKaptcha producer() {
Properties properties = new Properties();
properties.put("kaptcha.border", "no");
properties.put("kaptcha.textproducer.font.color", "black");
properties.put("kaptcha.textproducer.char.space", "10");
properties.put("kaptcha.textproducer.char.string", "1234567890");
properties.put("kaptcha.textproducer.char.length", "4");
Config config = new Config(properties);
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}

@ -0,0 +1,96 @@
package com.bjmashibing.shiro.shiro;
import com.bjmashibing.shiro.framework.util.R;
import com.bjmashibing.shiro.moduler.system.entity.LoginForm;
import com.bjmashibing.shiro.moduler.system.entity.User;
import com.bjmashibing.shiro.moduler.system.service.CaptchaService;
import com.bjmashibing.shiro.moduler.system.service.UserService;
import com.bjmashibing.shiro.moduler.system.service.UserTokenService;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Map;
/**
* <p></p>
*
* @author sunzhiqiang23
* @date 2020-05-23 13:30
*/
@RestController
public class LoginController {
@Autowired
private Producer producer;
@Autowired
private UserTokenService sysUserTokenService;
@Autowired
private UserService userService;
@Autowired
private CaptchaService captchaService;
/**
*
*/
@PostMapping("/sys/login")
public Map<String, Object> login(@RequestBody LoginForm form)throws IOException {
boolean captcha = captchaService.validate(form.getUuid(), form.getCaptcha());
if(!captcha){
return R.error("验证码不正确");
}
//用户信息
User user = userService.queryByUserName(form.getUsername());
//账号不存在、密码错误
if(user == null || !user.getPassword().equals(new Md5Hash(form.getPassword(), user.getSecretkey()).toHex())) {
return R.error("账号或密码不正确");
}
//账号锁定
if(user.getLocked() == 1){
return R.error("账号已被锁定,请联系管理员");
}
//生成token并保存到数据库
R r = sysUserTokenService.createToken(user.getId());
return r;
}
/**
* 退
*/
@PostMapping("/sys/logout")
public R logout() {
sysUserTokenService.logout(ShiroUtils.getUserId());
return R.ok();
}
/**
*
*/
@GetMapping("captcha.jpg")
public void captcha(HttpServletResponse response, String uuid)throws IOException {
response.setHeader("Cache-Control", "no-store, no-cache");
response.setContentType("image/jpeg");
//获取图片验证码
BufferedImage image = captchaService.getCaptcha(uuid);
ServletOutputStream out = response.getOutputStream();
ImageIO.write(image, "jpg", out);
IOUtils.closeQuietly(out);
}
}

@ -0,0 +1,113 @@
package com.bjmashibing.shiro.shiro;
import com.alibaba.fastjson.JSON;
import com.bjmashibing.shiro.framework.util.R;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* oauth2
*
* 401
*
*
*
* @author
* @date 2017-05-20 13:00
*/
public class OAuth2Filter extends AuthenticatingFilter {
@Override
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {
//获取请求token
String token = getRequestToken((HttpServletRequest) request);
if(StringUtils.isBlank(token)){
return null;
}
return new OAuth2Token(token);
}
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
if(((HttpServletRequest) request).getMethod().equals(RequestMethod.OPTIONS.name())){
return true;
}
// remeberMe ,remeberMe特殊页面需要授权
return false;
}
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
//获取请求token如果token不存在直接返回401
String token = getRequestToken((HttpServletRequest) request);
if(StringUtils.isBlank(token)){
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpResponse.setHeader("Access-Control-Allow-Origin", httpServletRequest.getHeader("Origin"));
String json = JSON.toJSONString(R.error(401, "invalid token"));
httpResponse.getWriter().print(json);
return false;
}
return executeLogin(request, response);
}
@Override
protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setContentType("application/json;charset=utf-8");
httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpResponse.setHeader("Access-Control-Allow-Origin", httpServletRequest.getHeader("Origin"));
try {
//处理登录失败的异常
Throwable throwable = e.getCause() == null ? e : e.getCause();
R r = R.error(401, throwable.getMessage());
String json = JSON.toJSONString(r);
httpResponse.getWriter().print(json);
} catch (IOException e1) {
}
return false;
}
/**
* token
*/
private String getRequestToken(HttpServletRequest httpRequest){
//从header中获取token
String token = httpRequest.getHeader("token");
//如果header中不存在token则从参数中获取token
if(StringUtils.isBlank(token)){
token = httpRequest.getParameter("token");
}
return token;
}
}

@ -0,0 +1,75 @@
package com.bjmashibing.shiro.shiro;
import com.bjmashibing.shiro.moduler.system.entity.UserToken;
import com.bjmashibing.shiro.moduler.system.entity.User;
import com.bjmashibing.shiro.moduler.system.service.ShiroService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Set;
/**
*
*
* @author
* @date 2017-05-20 14:00
*/
@Component
public class OAuth2Realm extends AuthorizingRealm {
@Autowired
private ShiroService shiroService;
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof OAuth2Token;
}
/**
* ()
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
User user = (User)principals.getPrimaryPrincipal();
Long userId = user.getId();
//用户权限列表
List<String> permsSet = shiroService.getUserPermissions(userId);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addStringPermissions(permsSet);
return info;
}
/**
* ()
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String accessToken = (String) token.getPrincipal();
//根据accessToken查询用户信息
// 实际中 token都存在集中式缓存组件中
UserToken tokenEntity = shiroService.queryByToken(accessToken);
//token失效
if(tokenEntity == null || tokenEntity.getExpireTime().getTime() < System.currentTimeMillis()){
throw new IncorrectCredentialsException("token失效请重新登录");
}
//查询用户信息
User user = shiroService.queryUser(tokenEntity.getUserId());
//账号锁定
if(user.getLocked() == 1){
throw new LockedAccountException("账号已被锁定,请联系管理员");
}
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, accessToken, getName());
return info;
}
}

@ -0,0 +1,29 @@
package com.bjmashibing.shiro.shiro;
import org.apache.shiro.authc.AuthenticationToken;
/**
* token
*
* @author
* @date 2017-05-20 13:22
*/
public class OAuth2Token implements AuthenticationToken {
private String token;
public OAuth2Token(String token){
this.token = token;
}
@Override
public String getPrincipal() {
return token;
}
@Override
public Object getCredentials() {
return token;
}
}

@ -0,0 +1,91 @@
package com.bjmashibing.shiro.shiro;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Shiro
*
* @author
* @date 2017-04-20 18:33
*/
@Configuration
public class ShiroConfig {
@Bean("sessionManager")
public SessionManager sessionManager(){
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setSessionValidationSchedulerEnabled(true);
sessionManager.setSessionIdCookieEnabled(true);
return sessionManager;
}
@Bean("securityManager")
public SecurityManager securityManager(OAuth2Realm oAuth2Realm, SessionManager sessionManager) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(oAuth2Realm);
securityManager.setSessionManager(sessionManager);
return securityManager;
}
@Bean("shiroFilter")
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
shiroFilter.setSecurityManager(securityManager);
//oauth过滤
Map<String, Filter> filters = new HashMap<>();
filters.put("oauth2", new OAuth2Filter());
shiroFilter.setFilters(filters);
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/webjars/**", "anon");
filterMap.put("/druid/**", "anon");
filterMap.put("/app/**", "anon");
filterMap.put("/sys/login", "anon");
filterMap.put("/swagger/**", "anon");
filterMap.put("/v2/api-docs", "anon");
filterMap.put("/swagger-ui.html", "anon");
filterMap.put("/swagger-resources/**", "anon");
filterMap.put("/captcha.jpg", "anon");
filterMap.put("/ueditor/**", "anon");
filterMap.put("/**", "oauth2");
shiroFilter.setFilterChainDefinitionMap(filterMap);
return shiroFilter;
}
@Bean("lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
proxyCreator.setProxyTargetClass(true);
return proxyCreator;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
}

@ -0,0 +1,83 @@
/**
* Copyright 2018 http://www.renren.io
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.bjmashibing.shiro.shiro;
import com.bjmashibing.shiro.moduler.system.entity.User;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
/**
* Shiro
*
* @author
* @date 20161112 9:49:19
*/
public class ShiroUtils {
/** 加密算法 */
public final static String hashAlgorithmName = "MD5";
/** 循环次数 */
public final static int hashIterations = 1;
public static String sha256(String password, String salt) {
return new SimpleHash(hashAlgorithmName, password, salt, hashIterations).toString();
}
public static Session getSession() {
return SecurityUtils.getSubject().getSession();
}
public static Subject getSubject() {
return SecurityUtils.getSubject();
}
public static User getUser() {
return (User) SecurityUtils.getSubject().getPrincipal();
}
public static Long getUserId() {
return getUser().getId();
}
public static void setSessionAttribute(Object key, Object value) {
getSession().setAttribute(key, value);
}
public static Object getSessionAttribute(Object key) {
return getSession().getAttribute(key);
}
public static boolean isLogin() {
return SecurityUtils.getSubject().getPrincipal() != null;
}
public static void logout() {
SecurityUtils.getSubject().logout();
}
public static String getKaptcha(String key) throws RuntimeException {
Object kaptcha = getSessionAttribute(key);
if(kaptcha == null){
throw new RuntimeException("验证码已失效");
}
getSession().removeAttribute(key);
return kaptcha.toString();
}
}

@ -0,0 +1,45 @@
package com.bjmashibing.shiro.shiro;
import java.security.MessageDigest;
import java.util.UUID;
/**
* token
*
* @author
* @date 2017-05-20 14:41
*/
public class TokenGenerator {
public static String generateValue() {
return generateValue(UUID.randomUUID().toString());
}
private static final char[] hexCode = "0123456789abcdef".toCharArray();
public static String toHexString(byte[] data) {
if(data == null) {
return null;
}
StringBuilder r = new StringBuilder(data.length*2);
for ( byte b : data) {
r.append(hexCode[(b >> 4) & 0xF]);
r.append(hexCode[(b & 0xF)]);
}
return r.toString();
}
public static String generateValue(String param) {
try {
MessageDigest algorithm = MessageDigest.getInstance("MD5");
algorithm.reset();
algorithm.update(param.getBytes());
byte[] messageDigest = algorithm.digest();
return toHexString(messageDigest);
} catch (Exception e) {
throw new RuntimeException("生成Token失败", e);
}
}
}

@ -0,0 +1,7 @@
# DataSource Config
spring:
datasource:
username: root
password: admin
url: jdbc:mysql://localhost:3306/db_shiro?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false
driver-class-name: com.mysql.jdbc.Driver

@ -0,0 +1,57 @@
# Tomcat
server:
tomcat:
uri-encoding: UTF-8
max-threads: 1000
min-spare-threads: 30
port: 9010
spring:
mvc:
static-path-pattern: /static/**
profiles:
active: db
freemarker:
suffix: .html
request-context-attribute: request
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
# 集群配置
redis:
expireSeconds: 60
timeout: 5000ms #redis操作的超时时间
database: 0
host: 192.168.254.201
port: 6379
#mybatis 插件
mybatis-plus:
mapper-locations: classpath:mapper/**/*.xml
#实体扫描多个package用逗号或者分号分隔
typeAliasesPackage: com.bjmashibing.shiro.moduler.*.entity
global-config:
db-config:
#主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
# id-type: uuid
id-type: auto
# id-type: id_worker
#字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
field-strategy: 2
#驼峰下划线转换
db-column-underline: true
#刷新mapper 调试神器
refresh-mapper: true
#数据库大写下划线转换
#capital-mode: true
#序列接口实现类配置
# key-generator: com.baomidou.springboot.xxx
#逻辑删除配置
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
#自定义填充策略接口实现
# meta-object-handler: com.baomidou.springboot.xxx
#自定义SQL注入器
# sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
call-setters-on-nulls: true

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bjmashibing.shiro.moduler.system.mapper.ModuleMapper">
</mapper>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bjmashibing.shiro.moduler.system.mapper.RoleMapper">
</mapper>

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bjmashibing.shiro.moduler.system.mapper.UserMapper">
<select id="queryAllPerms" resultType="java.lang.String">
SELECT
a.CODE
FROM
sys_module a,
sys_role_module_ref b,
sys_user_role_ref c
<where>
a.id = b.module_id
AND b.role_id = c.role_id
AND a.type IN ( 2, 3, 4 )
AND c.user_id =#{userId}
</where>
</select>
<select id="getRoleCodeList" resultType="java.lang.String">
select b.code from sys_user_role_ref a,sys_role b
<where>
and a.role_id=b.id
and a.user_id = #{userId}
</where>
</select>
<!-- 根据用户id查询菜单列表-->
<select id="findMenuListByUserId" resultType="com.bjmashibing.shiro.moduler.system.entity.Module">
SELECT
c.id,c.icon,c.name,c.url,c.parent_Id
FROM
sys_user_role_ref a,
sys_role_module_ref b,
sys_module c
WHERE
a.role_Id = b.role_Id
AND b.module_id = c.id
AND c.parent_id != -1
AND a.user_id = #{userId}
AND c.type=1
ORDER BY c.id
</select>
</mapper>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bjmashibing.shiro.moduler.system.mapper.UserTokenMapper">
<select id="queryByToken" resultType="com.bjmashibing.shiro.moduler.system.entity.UserToken">
select * from sys_user_token where token = #{value}
</select>
</mapper>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:'';content:none}table{border-collapse:collapse;border-spacing:0}

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
.swagger-section #header a#logo{font-size:1.5em;font-weight:700;text-decoration:none;padding:20px 0 20px 40px}#text-head{font-size:80px;font-family:Roboto,sans-serif;color:#fff;float:right;margin-right:20%}.navbar-fixed-top .navbar-brand,.navbar-fixed-top .navbar-nav,.navbar-header{height:auto}.navbar-inverse{background-color:#000;border-color:#000}#navbar-brand{margin-left:20%}.navtext{font-size:10px}.h1,h1{font-size:60px}.navbar-default .navbar-header .navbar-brand{color:#a2dfee}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a{color:#393939;font-family:Arvo,serif;font-size:1.5em}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2{color:#525252;padding-left:0;display:block;clear:none;float:left;font-family:Arvo,serif;font-weight:700}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#0a0a0a}.container1{width:1500px;margin:auto;margin-top:0;background-repeat:no-repeat;background-position:-40px -20px;margin-bottom:210px}.container-inner{width:1200px;margin:auto;background-color:hsla(192,8%,88%,.75);padding-bottom:40px;padding-top:40px;border-radius:15px}.header-content{padding:0;width:1000px}.title1{font-size:80px;font-family:Vollkorn,serif;color:#404040;text-align:center;padding-top:40px;padding-bottom:100px}#icon{margin-top:-18px}.subtext{font-size:25px;font-style:italic;color:#08b;text-align:right;padding-right:250px}.bg-primary{background-color:#00468b}.navbar-default .nav>li>a,.navbar-default .nav>li>a:focus,.navbar-default .nav>li>a:focus:hover,.navbar-default .nav>li>a:hover{color:#08b}.text-faded{font-size:25px;font-family:Vollkorn,serif}.section-heading{font-family:Vollkorn,serif;font-size:45px;padding-bottom:10px}hr{border-color:#00468b;padding-bottom:10px}.description{margin-top:20px;padding-bottom:200px}.description li{font-family:Vollkorn,serif;font-size:25px;color:#525252;margin-left:28%;padding-top:5px}.gap{margin-top:200px}.troubleshootingtext{color:hsla(0,0%,100%,.7);padding-left:30%}.troubleshootingtext li{list-style-type:circle;font-size:25px;padding-bottom:5px}.overlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1}.block.response_body.json:hover{cursor:pointer}.backdrop{color:blue}#myModal{height:100%}.modal-backdrop{bottom:0;position:fixed}.curl{padding:10px;font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;font-size:.9em;max-height:400px;margin-top:5px;overflow-y:auto;background-color:#fcf6db;border:1px solid #e5e0c6;border-radius:4px}.curl_title{font-size:1.1em;margin:0;padding:15px 0 5px;font-family:Open Sans,Helvetica Neue,Arial,sans-serif;font-weight:500;line-height:1.1}.footer{display:none}.swagger-section .swagger-ui-wrap h2{padding:0}h2{margin:0;margin-bottom:5px}.markdown p,.swagger-section .swagger-ui-wrap .code{font-size:15px;font-family:Arvo,serif}.swagger-section .swagger-ui-wrap b{font-family:Arvo,serif}#signin:hover{cursor:pointer}.dropdown-menu{padding:15px}.navbar-right .dropdown-menu{left:0;right:auto}#signinbutton{width:100%;height:32px;font-size:13px;font-weight:700;color:#08b}.navbar-default .nav>li .details{color:#000;text-transform:none;font-size:15px;font-weight:400;font-family:Open Sans,sans-serif;font-style:italic;line-height:20px;top:-2px}.navbar-default .nav>li .details:hover{color:#000}#signout{width:100%;height:32px;font-size:13px;font-weight:700;color:#08b}

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 631 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 B

@ -0,0 +1,107 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<title>接口文档</title>
<link rel="icon" type="image/png" href="/favicon.ico" />
<link href='css/typography.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='css/reset.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='css/reset.css' media='print' rel='stylesheet' type='text/css'/>
<link href='css/print.css' media='print' rel='stylesheet' type='text/css'/>
<script src='lib/object-assign-pollyfill.js' type='text/javascript'></script>
<script src='lib/jquery-1.8.0.min.js' type='text/javascript'></script>
<script src='lib/jquery.slideto.min.js' type='text/javascript'></script>
<script src='lib/jquery.wiggle.min.js' type='text/javascript'></script>
<script src='lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
<script src='lib/handlebars-4.0.5.js' type='text/javascript'></script>
<script src='lib/lodash.min.js' type='text/javascript'></script>
<script src='lib/backbone-min.js' type='text/javascript'></script>
<script src='swagger-ui.js' type='text/javascript'></script>
<script src='lib/highlight.9.1.0.pack.js' type='text/javascript'></script>
<script src='lib/highlight.9.1.0.pack_extended.js' type='text/javascript'></script>
<script src='lib/jsoneditor.min.js' type='text/javascript'></script>
<script src='lib/marked.js' type='text/javascript'></script>
<script src='lib/swagger-oauth.js' type='text/javascript'></script>
<!-- Some basic translations -->
<script src='lang/translator.js' type='text/javascript'></script>
<script src='lang/zh-cn.js' type='text/javascript'></script>
<script type="text/javascript">
$(function () {
var url = window.location.search.match(/url=([^&]+)/);
if (url && url.length > 1) {
url = decodeURIComponent(url[1]);
} else {
//url = "http://petstore.swagger.io/v2/swagger.json";
url = "../index.yaml";
}
hljs.configure({
highlightSizeThreshold: 5000
});
// Pre load translate...
if(window.SwaggerTranslator) {
window.SwaggerTranslator.translate();
}
window.swaggerUi = new SwaggerUi({
url: url,
dom_id: "swagger-ui-container",
supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
onComplete: function(swaggerApi, swaggerUi){
if(typeof initOAuth == "function") {
initOAuth({
clientId: "your-client-id",
clientSecret: "your-client-secret-if-required",
realm: "your-realms",
appName: "your-app-name",
scopeSeparator: " ",
additionalQueryStringParams: {}
});
}
if(window.SwaggerTranslator) {
window.SwaggerTranslator.translate();
}
},
onFailure: function(data) {
log("Unable to Load SwaggerUI");
},
docExpansion: "none",
jsonEditor: false,
defaultModelRendering: 'schema',
showRequestHeaders: false,
showOperationIds: false
});
window.swaggerUi.load();
function log() {
if ('console' in window) {
console.log.apply(console, arguments);
}
}
});
</script>
</head>
<body class="swagger-section">
<div id='header'>
<div class="swagger-ui-wrap">
<a id="logo" href="http://swagger.io"><img class="logo__img" alt="swagger" height="30" width="30" src="images/logo_small.png" /><span class="logo__title">swagger</span></a>
<form id='api_selector'>
<div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text"/></div>
<div id='auth_container'></div>
<div class='input'><a id="explore" class="header__btn" href="#" data-sw-translate>Explore</a></div>
</form>
</div>
</div>
<div id="message-bar" class="swagger-ui-wrap" data-sw-translate>&nbsp;</div>
<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
</body>
</html>

@ -0,0 +1,56 @@
'use strict';
/* jshint quotmark: double */
window.SwaggerTranslator.learn({
"Warning: Deprecated":"Warning: Deprecated",
"Implementation Notes":"Implementation Notes",
"Response Class":"Response Class",
"Status":"Status",
"Parameters":"Parameters",
"Parameter":"Parameter",
"Value":"Value",
"Description":"Description",
"Parameter Type":"Parameter Type",
"Data Type":"Data Type",
"Response Messages":"Response Messages",
"HTTP Status Code":"HTTP Status Code",
"Reason":"Reason",
"Response Model":"Response Model",
"Request URL":"Request URL",
"Response Body":"Response Body",
"Response Code":"Response Code",
"Response Headers":"Response Headers",
"Hide Response":"Hide Response",
"Headers":"Headers",
"Try it out!":"Try it out!",
"Show/Hide":"Show/Hide",
"List Operations":"List Operations",
"Expand Operations":"Expand Operations",
"Raw":"Raw",
"can't parse JSON. Raw result":"can't parse JSON. Raw result",
"Example Value":"Example Value",
"Model Schema":"Model Schema",
"Model":"Model",
"Click to set as parameter value":"Click to set as parameter value",
"apply":"apply",
"Username":"Username",
"Password":"Password",
"Terms of service":"Terms of service",
"Created by":"Created by",
"See more at":"See more at",
"Contact the developer":"Contact the developer",
"api version":"api version",
"Response Content Type":"Response Content Type",
"Parameter content type:":"Parameter content type:",
"fetching resource":"fetching resource",
"fetching resource list":"fetching resource list",
"Explore":"Explore",
"Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis",
"Can't read from server. It may not have the appropriate access-control-origin settings.":"Can't read from server. It may not have the appropriate access-control-origin settings.",
"Please specify the protocol for":"Please specify the protocol for",
"Can't read swagger JSON from":"Can't read swagger JSON from",
"Finished Loading Resource Information. Rendering Swagger UI":"Finished Loading Resource Information. Rendering Swagger UI",
"Unable to read api":"Unable to read api",
"from path":"from path",
"server returned":"server returned"
});

@ -0,0 +1,39 @@
'use strict';
/**
* Translator for documentation pages.
*
* To enable translation you should include one of language-files in your index.html
* after <script src='lang/translator.js' type='text/javascript'></script>.
* For example - <script src='lang/ru.js' type='text/javascript'></script>
*
* If you wish to translate some new texts you should do two things:
* 1. Add a new phrase pair ("New Phrase": "New Translation") into your language file (for example lang/ru.js). It will be great if you add it in other language files too.
* 2. Mark that text it templates this way <anyHtmlTag data-sw-translate>New Phrase</anyHtmlTag> or <anyHtmlTag data-sw-translate value='New Phrase'/>.
* The main thing here is attribute data-sw-translate. Only inner html, title-attribute and value-attribute are going to translate.
*
*/
window.SwaggerTranslator = {
_words:[],
translate: function(sel) {
var $this = this;
sel = sel || '[data-sw-translate]';
$(sel).each(function() {
$(this).html($this._tryTranslate($(this).html()));
$(this).val($this._tryTranslate($(this).val()));
$(this).attr('title', $this._tryTranslate($(this).attr('title')));
});
},
_tryTranslate: function(word) {
return this._words[$.trim(word)] !== undefined ? this._words[$.trim(word)] : word;
},
learn: function(wordsMap) {
this._words = wordsMap;
}
};

@ -0,0 +1,56 @@
'use strict';
/* jshint quotmark: double */
window.SwaggerTranslator.learn({
"Warning: Deprecated":"警告:已过时",
"Implementation Notes":"接口备注",
"Response Class":"响应类",
"Status":"状态",
"Parameters":"参数",
"Parameter":"参数",
"Value":"值",
"Description":"描述",
"Parameter Type":"参数类型",
"Data Type":"数据类型",
"Response Messages":"响应消息",
"HTTP Status Code":"HTTP状态码",
"Reason":"原因",
"Response Model":"响应模型",
"Request URL":"请求URL",
"Response Body":"响应体",
"Response Code":"响应码",
"Response Headers":"响应头",
"Hide Response":"隐藏响应",
"Headers":"头",
"Try it out!":"试一下!",
"Show/Hide":"显示/隐藏",
"List Operations":"显示操作",
"Expand Operations":"展开操作",
"Raw":"原始",
"can't parse JSON. Raw result":"无法解析JSON. 原始结果",
"Example Value":"示例",
"Click to set as parameter value":"点击设置参数",
"Model Schema":"模型架构",
"Model":"模型",
"apply":"应用",
"Username":"用户名",
"Password":"密码",
"Terms of service":"服务条款",
"Created by":"创建者",
"See more at":"查看更多:",
"Contact the developer":"联系开发者",
"api version":"api版本",
"Response Content Type":"响应类型",
"Parameter content type:":"参数类型:",
"fetching resource":"正在获取资源",
"fetching resource list":"正在获取资源列表",
"Explore":"浏览",
"Show Swagger Petstore Example Apis":"显示 Swagger Petstore 示例 Apis",
"Can't read from server. It may not have the appropriate access-control-origin settings.":"无法从服务器读取。可能没有正确设置access-control-origin。",
"Please specify the protocol for":"请指定协议:",
"Can't read swagger JSON from":"无法读取swagger JSON于",
"Finished Loading Resource Information. Rendering Swagger UI":"已加载资源信息。正在渲染Swagger UI",
"Unable to read api":"无法读取api",
"from path":"从路径",
"server returned":"服务器返回"
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
"use strict";!function(){var h,l;h=hljs.configure,hljs.configure=function(l){var i=l.highlightSizeThreshold;hljs.highlightSizeThreshold=i===+i?i:null,h.call(this,l)},l=hljs.highlightBlock,hljs.highlightBlock=function(h){var i=h.innerHTML,g=hljs.highlightSizeThreshold;(null==g||g>i.length)&&l.call(hljs,h)}}();

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
!function(e,t){function n(e){return"string"==typeof e}function r(e){var t=g.call(arguments,1);return function(){return e.apply(this,t.concat(g.call(arguments)))}}function o(e){return e.replace(/^[^#]*#?(.*)$/,"$1")}function a(e){return e.replace(/(?:^[^?#]*\?([^#]*).*$)?.*/,"$1")}function i(r,o,a,i,c){var u,s,p,h,d;return i!==f?(p=a.match(r?/^([^#]*)\#?(.*)$/:/^([^#?]*)\??([^#]*)(#?.*)/),d=p[3]||"",2===c&&n(i)?s=i.replace(r?R:E,""):(h=l(p[2]),i=n(i)?l[r?A:w](i):i,s=2===c?i:1===c?e.extend({},i,h):e.extend({},h,i),s=b(s),r&&(s=s.replace(m,y))),u=p[1]+(r?"#":s||!p[1]?"?":"")+s+d):u=o(a!==f?a:t[S][q]),u}function c(e,t,r){return t===f||"boolean"==typeof t?(r=t,t=b[e?A:w]()):t=n(t)?t.replace(e?R:E,""):t,l(t,r)}function u(t,r,o,a){return n(o)||"object"==typeof o||(a=o,o=r,r=f),this.each(function(){var n=e(this),i=r||v()[(this.nodeName||"").toLowerCase()]||"",c=i&&n.attr(i)||"";n.attr(i,b[t](c,o,a))})}var f,s,l,p,h,d,v,m,g=Array.prototype.slice,y=decodeURIComponent,b=e.param,$=e.bbq=e.bbq||{},x=e.event.special,j="hashchange",w="querystring",A="fragment",N="elemUrlAttr",S="location",q="href",C="src",E=/^.*\?|#.*$/g,R=/^.*\#/,U={};b[w]=r(i,0,a),b[A]=s=r(i,1,o),s.noEscape=function(t){t=t||"";var n=e.map(t.split(""),encodeURIComponent);m=new RegExp(n.join("|"),"g")},s.noEscape(",/"),e.deparam=l=function(t,n){var r={},o={"true":!0,"false":!1,"null":null};return e.each(t.replace(/\+/g," ").split("&"),function(t,a){var i,c=a.split("="),u=y(c[0]),s=r,l=0,p=u.split("]["),h=p.length-1;if(/\[/.test(p[0])&&/\]$/.test(p[h])?(p[h]=p[h].replace(/\]$/,""),p=p.shift().split("[").concat(p),h=p.length-1):h=0,2===c.length)if(i=y(c[1]),n&&(i=i&&!isNaN(i)?+i:"undefined"===i?f:o[i]!==f?o[i]:i),h)for(;l<=h;l++)u=""===p[l]?s.length:p[l],s=s[u]=l<h?s[u]||(p[l+1]&&isNaN(p[l+1])?{}:[]):i;else e.isArray(r[u])?r[u].push(i):r[u]!==f?r[u]=[r[u],i]:r[u]=i;else u&&(r[u]=n?f:"")}),r},l[w]=r(c,0),l[A]=p=r(c,1),e[N]||(e[N]=function(t){return e.extend(U,t)})({a:q,base:q,iframe:C,img:C,input:C,form:"action",link:q,script:C}),v=e[N],e.fn[w]=r(u,w),e.fn[A]=r(u,A),$.pushState=h=function(e,r){n(e)&&/^#/.test(e)&&r===f&&(r=2);var o=e!==f,a=s(t[S][q],o?e:{},o?r:2);t[S][q]=a+(/#/.test(a)?"":"#")},$.getState=d=function(e,t){return e===f||"boolean"==typeof e?p(e):p(t)[e]},$.removeState=function(t){var n={};t!==f&&(n=d(),e.each(e.isArray(t)?t:arguments,function(e,t){delete n[t]})),h(n,2)},x[j]=e.extend(x[j],{add:function(t){function n(e){var t=e[A]=s();e.getState=function(e,n){return e===f||"boolean"==typeof e?l(t,e):l(t,n)[e]},r.apply(this,arguments)}var r;return e.isFunction(t)?(r=t,n):(r=t.handler,void(t.handler=n))}})}(jQuery,this),function(e,t,n){function r(e){return e=e||t[i][u],e.replace(/^[^#]*#?(.*)$/,"$1")}var o,a=e.event.special,i="location",c="hashchange",u="href",f=e.browser,s=document.documentMode,l=f.msie&&(s===n||s<8),p="on"+c in t&&!l;e[c+"Delay"]=100,a[c]=e.extend(a[c],{setup:function(){return!p&&void e(o.start)},teardown:function(){return!p&&void e(o.stop)}}),o=function(){function n(){f=s=function(e){return e},l&&(a=e('<iframe src="javascript:0"/>').hide().insertAfter("body")[0].contentWindow,s=function(){return r(a.document[i][u])},(f=function(e,t){if(e!==t){var n=a.document;n.open().close(),n[i].hash="#"+e}})(r()))}var o,a,f,s,p={};return p.start=function(){if(!o){var a=r();f||n(),function l(){var n=r(),p=s(a);n!==a?(f(a=n,p),e(t).trigger(c)):p!==a&&(t[i][u]=t[i][u].replace(/#.*/,"")+"#"+p),o=setTimeout(l,e[c+"Delay"])}()}},p.stop=function(){a||(o&&clearTimeout(o),o=0)},p}()}(jQuery,this);

@ -0,0 +1 @@
!function(i){i.fn.slideto=function(o){return o=i.extend({slide_duration:"slow",highlight_duration:3e3,highlight:!0,highlight_color:"#FFFF99"},o),this.each(function(){obj=i(this),i("body").animate({scrollTop:obj.offset().top},o.slide_duration,function(){o.highlight&&i.ui.version&&obj.effect("highlight",{color:o.highlight_color},o.highlight_duration)})})}}(jQuery);

@ -0,0 +1 @@
jQuery.fn.wiggle=function(e){var a={speed:50,wiggles:3,travel:5,callback:null},e=jQuery.extend(a,e);return this.each(function(){var a=this,l=(jQuery(this).wrap('<div class="wiggle-wrap"></div>').css("position","relative"),0);for(i=1;i<=e.wiggles;i++)jQuery(this).animate({left:"-="+e.travel},e.speed).animate({left:"+="+2*e.travel},2*e.speed).animate({left:"-="+e.travel},e.speed,function(){l++,jQuery(a).parent().hasClass("wiggle-wrap")&&jQuery(a).parent().replaceWith(a),l==e.wiggles&&jQuery.isFunction(e.callback)&&e.callback()})})};

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save