forked from wuyouzhuguli/SpringAll
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c456b2c
commit 697951d
Showing
23 changed files
with
1,152 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
<?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> | ||
<parent> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-parent</artifactId> | ||
<version>2.1.0.RELEASE</version> | ||
<relativePath/> <!-- lookup parent from repository --> | ||
</parent> | ||
<groupId>com.example</groupId> | ||
<artifactId>demo</artifactId> | ||
<version>0.0.1-SNAPSHOT</version> | ||
<name>springboot-shiro-jwt-demo</name> | ||
<description>springboot整合shiro,jwt简单样例</description> | ||
|
||
<properties> | ||
<java.version>1.8</java.version> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-web</artifactId> | ||
</dependency> | ||
<!-- shiro-spring --> | ||
<dependency> | ||
<groupId>org.apache.shiro</groupId> | ||
<artifactId>shiro-spring</artifactId> | ||
<version>1.4.0</version> | ||
</dependency> | ||
<!-- jwt --> | ||
<dependency> | ||
<groupId>com.auth0</groupId> | ||
<artifactId>java-jwt</artifactId> | ||
<version>3.4.1</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-aop</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.commons</groupId> | ||
<artifactId>commons-lang3</artifactId> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-maven-plugin</artifactId> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
|
||
</project> |
23 changes: 23 additions & 0 deletions
23
62.Spring-Boot-Shiro-JWT/src/main/java/com/example/demo/DemoApplication.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package com.example.demo; | ||
|
||
import com.example.demo.properties.SystemProperties; | ||
import org.springframework.boot.Banner; | ||
import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
import org.springframework.boot.builder.SpringApplicationBuilder; | ||
import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||
|
||
/** | ||
* | ||
* @author MrBird | ||
*/ | ||
@SpringBootApplication | ||
@EnableConfigurationProperties(SystemProperties.class) | ||
public class DemoApplication { | ||
|
||
public static void main(String[] args) { | ||
new SpringApplicationBuilder(DemoApplication.class) | ||
.bannerMode(Banner.Mode.OFF) | ||
.run(args); | ||
} | ||
|
||
} |
87 changes: 87 additions & 0 deletions
87
62.Spring-Boot-Shiro-JWT/src/main/java/com/example/demo/authentication/JWTFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package com.example.demo.authentication; | ||
|
||
import com.example.demo.properties.SystemProperties; | ||
import com.example.demo.utils.SpringContextUtil; | ||
import org.apache.commons.lang3.StringUtils; | ||
import org.apache.shiro.authz.UnauthorizedException; | ||
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.util.AntPathMatcher; | ||
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; | ||
|
||
/** | ||
* | ||
* @author MrBird | ||
*/ | ||
public class JWTFilter extends BasicHttpAuthenticationFilter { | ||
|
||
private Logger log = LoggerFactory.getLogger(this.getClass()); | ||
|
||
private static final String TOKEN = "Token"; | ||
|
||
private AntPathMatcher pathMatcher = new AntPathMatcher(); | ||
|
||
@Override | ||
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws UnauthorizedException { | ||
HttpServletRequest httpServletRequest = (HttpServletRequest) request; | ||
SystemProperties properties = SpringContextUtil.getBean(SystemProperties.class); | ||
String[] anonUrl = StringUtils.splitByWholeSeparatorPreserveAllTokens(properties.getAnonUrl(), ","); | ||
|
||
boolean match = false; | ||
for (String u : anonUrl) { | ||
if (pathMatcher.match(u, httpServletRequest.getRequestURI())) | ||
match = true; | ||
} | ||
if (match) return true; | ||
if (isLoginAttempt(request, response)) { | ||
return executeLogin(request, response); | ||
} | ||
return false; | ||
} | ||
|
||
@Override | ||
protected boolean isLoginAttempt(ServletRequest request, ServletResponse response) { | ||
HttpServletRequest req = (HttpServletRequest) request; | ||
String token = req.getHeader(TOKEN); | ||
return token != null; | ||
} | ||
|
||
@Override | ||
protected boolean executeLogin(ServletRequest request, ServletResponse response) { | ||
HttpServletRequest httpServletRequest = (HttpServletRequest) request; | ||
String token = httpServletRequest.getHeader(TOKEN); | ||
JWTToken jwtToken = new JWTToken(token); | ||
try { | ||
getSubject(request, response).login(jwtToken); | ||
return true; | ||
} catch (Exception e) { | ||
log.error(e.getMessage()); | ||
return false; | ||
} | ||
} | ||
|
||
/** | ||
* 对跨域提供支持 | ||
*/ | ||
@Override | ||
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception { | ||
HttpServletRequest httpServletRequest = (HttpServletRequest) request; | ||
HttpServletResponse httpServletResponse = (HttpServletResponse) response; | ||
httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin")); | ||
httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE"); | ||
httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers")); | ||
// 跨域时会首先发送一个 option请求,这里我们给 option请求直接返回正常状态 | ||
if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) { | ||
httpServletResponse.setStatus(HttpStatus.OK.value()); | ||
return false; | ||
} | ||
return super.preHandle(request, response); | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
62.Spring-Boot-Shiro-JWT/src/main/java/com/example/demo/authentication/JWTToken.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package com.example.demo.authentication; | ||
|
||
import org.apache.shiro.authc.AuthenticationToken; | ||
|
||
/** | ||
* JSON Web Token | ||
* | ||
* @author MrBird | ||
*/ | ||
public class JWTToken implements AuthenticationToken { | ||
|
||
private static final long serialVersionUID = 1282057025599826155L; | ||
|
||
private String token; | ||
|
||
private String exipreAt; | ||
|
||
public JWTToken(String token) { | ||
this.token = token; | ||
} | ||
|
||
public JWTToken(String token, String exipreAt) { | ||
this.token = token; | ||
this.exipreAt = exipreAt; | ||
} | ||
|
||
@Override | ||
public Object getPrincipal() { | ||
return token; | ||
} | ||
|
||
@Override | ||
public Object getCredentials() { | ||
return token; | ||
} | ||
|
||
public String getToken() { | ||
return token; | ||
} | ||
|
||
public void setToken(String token) { | ||
this.token = token; | ||
} | ||
|
||
public String getExipreAt() { | ||
return exipreAt; | ||
} | ||
|
||
public void setExipreAt(String exipreAt) { | ||
this.exipreAt = exipreAt; | ||
} | ||
} |
84 changes: 84 additions & 0 deletions
84
62.Spring-Boot-Shiro-JWT/src/main/java/com/example/demo/authentication/JWTUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package com.example.demo.authentication; | ||
|
||
import com.auth0.jwt.JWT; | ||
import com.auth0.jwt.JWTVerifier; | ||
import com.auth0.jwt.algorithms.Algorithm; | ||
import com.auth0.jwt.exceptions.JWTDecodeException; | ||
import com.auth0.jwt.interfaces.DecodedJWT; | ||
import com.example.demo.properties.SystemProperties; | ||
import com.example.demo.utils.SpringContextUtil; | ||
import org.apache.commons.lang3.StringUtils; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.util.Date; | ||
|
||
/** | ||
* | ||
* @author MrBird | ||
*/ | ||
public class JWTUtil { | ||
|
||
private static Logger log = LoggerFactory.getLogger(JWTUtil.class); | ||
|
||
private static final long EXPIRE_TIME = SpringContextUtil.getBean(SystemProperties.class).getJwtTimeOut() * 1000; | ||
|
||
/** | ||
* 校验 token是否正确 | ||
* | ||
* @param token 密钥 | ||
* @param secret 用户的密码 | ||
* @return 是否正确 | ||
*/ | ||
public static boolean verify(String token, String username, String secret) { | ||
try { | ||
Algorithm algorithm = Algorithm.HMAC256(secret); | ||
JWTVerifier verifier = JWT.require(algorithm) | ||
.withClaim("username", username) | ||
.build(); | ||
verifier.verify(token); | ||
log.info("token is valid"); | ||
return true; | ||
} catch (Exception e) { | ||
log.info("token is invalid{}", e.getMessage()); | ||
return false; | ||
} | ||
} | ||
|
||
/** | ||
* 从 token中获取用户名 | ||
* | ||
* @return token中包含的用户名 | ||
*/ | ||
public static String getUsername(String token) { | ||
try { | ||
DecodedJWT jwt = JWT.decode(token); | ||
return jwt.getClaim("username").asString(); | ||
} catch (JWTDecodeException e) { | ||
log.error("error:{}", e.getMessage()); | ||
return null; | ||
} | ||
} | ||
|
||
/** | ||
* 生成 token | ||
* | ||
* @param username 用户名 | ||
* @param secret 用户的密码 | ||
* @return token | ||
*/ | ||
public static String sign(String username, String secret) { | ||
try { | ||
username = StringUtils.lowerCase(username); | ||
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME); | ||
Algorithm algorithm = Algorithm.HMAC256(secret); | ||
return JWT.create() | ||
.withClaim("username", username) | ||
.withExpiresAt(date) | ||
.sign(algorithm); | ||
} catch (Exception e) { | ||
log.error("error:{}", e); | ||
return null; | ||
} | ||
} | ||
} |
60 changes: 60 additions & 0 deletions
60
62.Spring-Boot-Shiro-JWT/src/main/java/com/example/demo/authentication/ShiroConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package com.example.demo.authentication; | ||
|
||
import org.apache.shiro.mgt.SecurityManager; | ||
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; | ||
import org.apache.shiro.spring.web.ShiroFilterFactoryBean; | ||
import org.apache.shiro.web.mgt.DefaultWebSecurityManager; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
import javax.servlet.Filter; | ||
import java.util.LinkedHashMap; | ||
|
||
/** | ||
* Shiro 配置类 | ||
* | ||
* @author MrBird | ||
*/ | ||
@Configuration | ||
public class ShiroConfig { | ||
|
||
@Bean | ||
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { | ||
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); | ||
// 设置 securityManager | ||
shiroFilterFactoryBean.setSecurityManager(securityManager); | ||
|
||
// 在 Shiro过滤器链上加入 JWTFilter | ||
LinkedHashMap<String, Filter> filters = new LinkedHashMap<>(); | ||
filters.put("jwt", new JWTFilter()); | ||
shiroFilterFactoryBean.setFilters(filters); | ||
|
||
LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); | ||
// 所有请求都要经过 jwt过滤器 | ||
filterChainDefinitionMap.put("/**", "jwt"); | ||
|
||
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); | ||
return shiroFilterFactoryBean; | ||
} | ||
|
||
@Bean | ||
public SecurityManager securityManager() { | ||
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); | ||
// 配置 SecurityManager,并注入 shiroRealm | ||
securityManager.setRealm(shiroRealm()); | ||
return securityManager; | ||
} | ||
|
||
@Bean | ||
public ShiroRealm shiroRealm() { | ||
// 配置 Realm | ||
return new ShiroRealm(); | ||
} | ||
|
||
@Bean | ||
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { | ||
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); | ||
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); | ||
return authorizationAttributeSourceAdvisor; | ||
} | ||
} |
Oops, something went wrong.