Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
guns-vip
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
chenjunxiong
guns-vip
Commits
7b901b3c
Commit
7b901b3c
authored
Jul 20, 2018
by
stylefeng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
admin增加对jwt的依赖
parent
98fe8194
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
264 additions
and
21 deletions
+264
-21
guns-admin/pom.xml
+5
-0
guns-admin/src/main/java/com/stylefeng/guns/config/web/ShiroConfig.java
+3
-0
guns-admin/src/main/java/com/stylefeng/guns/config/web/WebConfig.java
+10
-0
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/JwtConstants.java
+19
-0
guns-admin/src/main/java/com/stylefeng/guns/core/common/exception/BizExceptionEnum.java
+37
-21
guns-admin/src/main/java/com/stylefeng/guns/core/intercept/RestApiInteceptor.java
+62
-0
guns-admin/src/main/java/com/stylefeng/guns/core/util/JwtTokenUtil.java
+128
-0
No files found.
guns-admin/pom.xml
View file @
7b901b3c
...
...
@@ -115,6 +115,11 @@
<artifactId>
springfox-swagger-ui
</artifactId>
</dependency>
<dependency>
<groupId>
io.jsonwebtoken
</groupId>
<artifactId>
jjwt
</artifactId>
</dependency>
</dependencies>
<build>
...
...
guns-admin/src/main/java/com/stylefeng/guns/config/web/ShiroConfig.java
View file @
7b901b3c
...
...
@@ -156,9 +156,12 @@ public class ShiroConfig {
*
* 顺序从上到下,优先级依次降低
*
* api开头的接口,走rest api鉴权,不走shiro鉴权
*
*/
Map
<
String
,
String
>
hashMap
=
new
LinkedHashMap
<>();
hashMap
.
put
(
"/static/**"
,
"anon"
);
hashMap
.
put
(
"/api/**"
,
"anon"
);
hashMap
.
put
(
"/login"
,
"anon"
);
hashMap
.
put
(
"/global/sessionError"
,
"anon"
);
hashMap
.
put
(
"/kaptcha"
,
"anon"
);
...
...
guns-admin/src/main/java/com/stylefeng/guns/config/web/WebConfig.java
View file @
7b901b3c
...
...
@@ -8,6 +8,7 @@ import com.alibaba.druid.support.spring.stat.DruidStatInterceptor;
import
com.google.code.kaptcha.impl.DefaultKaptcha
;
import
com.google.code.kaptcha.util.Config
;
import
com.stylefeng.guns.config.properties.GunsProperties
;
import
com.stylefeng.guns.core.intercept.RestApiInteceptor
;
import
com.stylefeng.guns.core.listener.ConfigListener
;
import
com.stylefeng.guns.core.xss.XssFilter
;
import
org.springframework.aop.Advisor
;
...
...
@@ -20,6 +21,7 @@ import org.springframework.boot.web.servlet.ServletRegistrationBean;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.web.context.request.RequestContextListener
;
import
org.springframework.web.servlet.config.annotation.InterceptorRegistry
;
import
org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
;
import
org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
;
...
...
@@ -50,6 +52,14 @@ public class WebConfig extends WebMvcConfigurerAdapter {
}
/**
* 增加对rest api鉴权的spring mvc拦截器
*/
@Override
public
void
addInterceptors
(
InterceptorRegistry
registry
)
{
registry
.
addInterceptor
(
new
RestApiInteceptor
()).
addPathPatterns
(
"/api/**"
);
}
/**
* druidServlet注册
*/
@Bean
...
...
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/JwtConstants.java
0 → 100644
View file @
7b901b3c
package
com
.
stylefeng
.
guns
.
core
.
common
.
constant
;
/**
* jwt相关配置
*
* @author fengshuonan
* @date 2017-08-23 9:23
*/
public
interface
JwtConstants
{
String
AUTH_HEADER
=
"Authorization"
;
String
SECRET
=
"defaultSecret"
;
Long
EXPIRATION
=
604800L
;
String
AUTH_PATH
=
"/api/auth"
;
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/exception/BizExceptionEnum.java
View file @
7b901b3c
...
...
@@ -3,43 +3,43 @@ package com.stylefeng.guns.core.common.exception;
import
com.stylefeng.guns.core.exception.ServiceExceptionEnum
;
/**
* @Description 所有业务异常的枚举
* @author fengshuonan
* @Description 所有业务异常的枚举
* @date 2016年11月12日 下午5:04:51
*/
public
enum
BizExceptionEnum
implements
ServiceExceptionEnum
{
public
enum
BizExceptionEnum
implements
ServiceExceptionEnum
{
/**
* 字典
*/
DICT_EXISTED
(
400
,
"字典已经存在"
),
ERROR_CREATE_DICT
(
500
,
"创建字典失败"
),
ERROR_WRAPPER_FIELD
(
500
,
"包装字典属性失败"
),
ERROR_CODE_EMPTY
(
500
,
"字典类型不能为空"
),
DICT_EXISTED
(
400
,
"字典已经存在"
),
ERROR_CREATE_DICT
(
500
,
"创建字典失败"
),
ERROR_WRAPPER_FIELD
(
500
,
"包装字典属性失败"
),
ERROR_CODE_EMPTY
(
500
,
"字典类型不能为空"
),
/**
* 文件上传
*/
FILE_READING_ERROR
(
400
,
"FILE_READING_ERROR!"
),
FILE_NOT_FOUND
(
400
,
"FILE_NOT_FOUND!"
),
UPLOAD_ERROR
(
500
,
"上传图片出错"
),
FILE_READING_ERROR
(
400
,
"FILE_READING_ERROR!"
),
FILE_NOT_FOUND
(
400
,
"FILE_NOT_FOUND!"
),
UPLOAD_ERROR
(
500
,
"上传图片出错"
),
/**
* 权限和数据问题
*/
DB_RESOURCE_NULL
(
400
,
"数据库中没有该资源"
),
DB_RESOURCE_NULL
(
400
,
"数据库中没有该资源"
),
NO_PERMITION
(
405
,
"权限异常"
),
REQUEST_INVALIDATE
(
400
,
"请求数据格式不正确"
),
INVALID_KAPTCHA
(
400
,
"验证码不正确"
),
CANT_DELETE_ADMIN
(
600
,
"不能删除超级管理员"
),
CANT_FREEZE_ADMIN
(
600
,
"不能冻结超级管理员"
),
CANT_CHANGE_ADMIN
(
600
,
"不能修改超级管理员角色"
),
REQUEST_INVALIDATE
(
400
,
"请求数据格式不正确"
),
INVALID_KAPTCHA
(
400
,
"验证码不正确"
),
CANT_DELETE_ADMIN
(
600
,
"不能删除超级管理员"
),
CANT_FREEZE_ADMIN
(
600
,
"不能冻结超级管理员"
),
CANT_CHANGE_ADMIN
(
600
,
"不能修改超级管理员角色"
),
/**
* 账户问题
*/
USER_ALREADY_REG
(
401
,
"该用户已经注册"
),
NO_THIS_USER
(
400
,
"没有此用户"
),
USER_ALREADY_REG
(
401
,
"该用户已经注册"
),
NO_THIS_USER
(
400
,
"没有此用户"
),
USER_NOT_EXISTED
(
400
,
"没有此用户"
),
ACCOUNT_FREEZED
(
401
,
"账号被冻结"
),
OLD_PWD_NOT_RIGHT
(
402
,
"原密码不正确"
),
...
...
@@ -48,12 +48,28 @@ public enum BizExceptionEnum implements ServiceExceptionEnum{
/**
* 错误的请求
*/
MENU_PCODE_COINCIDENCE
(
400
,
"菜单编号和副编号不能一致"
),
EXISTED_THE_MENU
(
400
,
"菜单编号重复,不能添加"
),
DICT_MUST_BE_NUMBER
(
400
,
"字典的值必须为数字"
),
MENU_PCODE_COINCIDENCE
(
400
,
"菜单编号和副编号不能一致"
),
EXISTED_THE_MENU
(
400
,
"菜单编号重复,不能添加"
),
DICT_MUST_BE_NUMBER
(
400
,
"字典的值必须为数字"
),
REQUEST_NULL
(
400
,
"请求有错误"
),
SESSION_TIMEOUT
(
400
,
"会话超时"
),
SERVER_ERROR
(
500
,
"服务器异常"
);
SERVER_ERROR
(
500
,
"服务器异常"
),
/**
* token异常
*/
TOKEN_EXPIRED
(
700
,
"token过期"
),
TOKEN_ERROR
(
700
,
"token验证失败"
),
/**
* 签名异常
*/
SIGN_ERROR
(
700
,
"签名验证失败"
),
/**
* 其他
*/
AUTH_REQUEST_ERROR
(
400
,
"账号密码错误"
);
BizExceptionEnum
(
int
code
,
String
message
)
{
this
.
code
=
code
;
...
...
guns-admin/src/main/java/com/stylefeng/guns/core/intercept/RestApiInteceptor.java
0 → 100644
View file @
7b901b3c
package
com
.
stylefeng
.
guns
.
core
.
intercept
;
import
com.stylefeng.guns.core.base.tips.ErrorTip
;
import
com.stylefeng.guns.core.common.constant.JwtConstants
;
import
com.stylefeng.guns.core.common.exception.BizExceptionEnum
;
import
com.stylefeng.guns.core.util.JwtTokenUtil
;
import
com.stylefeng.guns.core.util.RenderUtil
;
import
io.jsonwebtoken.JwtException
;
import
org.springframework.web.method.HandlerMethod
;
import
org.springframework.web.servlet.handler.HandlerInterceptorAdapter
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
/**
* Rest Api接口鉴权
*
* @author stylefeng
* @Date 2018/7/20 23:11
*/
public
class
RestApiInteceptor
extends
HandlerInterceptorAdapter
{
@Override
public
boolean
preHandle
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
)
throws
Exception
{
if
(
handler
instanceof
org
.
springframework
.
web
.
servlet
.
resource
.
ResourceHttpRequestHandler
)
{
return
true
;
}
HandlerMethod
handlerMethod
=
(
HandlerMethod
)
handler
;
return
check
(
request
,
response
,
handlerMethod
);
}
private
boolean
check
(
HttpServletRequest
request
,
HttpServletResponse
response
,
HandlerMethod
handlerMethod
)
{
if
(
request
.
getServletPath
().
equals
(
JwtConstants
.
AUTH_PATH
))
{
return
true
;
}
final
String
requestHeader
=
request
.
getHeader
(
JwtConstants
.
AUTH_HEADER
);
String
authToken
;
if
(
requestHeader
!=
null
&&
requestHeader
.
startsWith
(
"Bearer "
))
{
authToken
=
requestHeader
.
substring
(
7
);
//验证token是否过期,包含了验证jwt是否正确
try
{
boolean
flag
=
JwtTokenUtil
.
isTokenExpired
(
authToken
);
if
(
flag
)
{
RenderUtil
.
renderJson
(
response
,
new
ErrorTip
(
BizExceptionEnum
.
TOKEN_EXPIRED
.
getCode
(),
BizExceptionEnum
.
TOKEN_EXPIRED
.
getMessage
()));
return
false
;
}
}
catch
(
JwtException
e
)
{
//有异常就是token解析失败
RenderUtil
.
renderJson
(
response
,
new
ErrorTip
(
BizExceptionEnum
.
TOKEN_ERROR
.
getCode
(),
BizExceptionEnum
.
TOKEN_ERROR
.
getMessage
()));
return
false
;
}
}
else
{
//header没有带Bearer字段
RenderUtil
.
renderJson
(
response
,
new
ErrorTip
(
BizExceptionEnum
.
TOKEN_ERROR
.
getCode
(),
BizExceptionEnum
.
TOKEN_ERROR
.
getMessage
()));
return
false
;
}
return
true
;
}
}
guns-admin/src/main/java/com/stylefeng/guns/core/util/JwtTokenUtil.java
0 → 100644
View file @
7b901b3c
package
com
.
stylefeng
.
guns
.
core
.
util
;
import
com.stylefeng.guns.core.common.constant.JwtConstants
;
import
io.jsonwebtoken.*
;
import
org.springframework.stereotype.Component
;
import
java.util.Date
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* <p>jwt token工具类</p>
* <pre>
* jwt的claim里一般包含以下几种数据:
* 1. iss -- token的发行者
* 2. sub -- 该JWT所面向的用户
* 3. aud -- 接收该JWT的一方
* 4. exp -- token的失效时间
* 5. nbf -- 在此时间段之前,不会被处理
* 6. iat -- jwt发布时间
* 7. jti -- jwt唯一标识,防止重复使用
* </pre>
*
* @author fengshuonan
* @Date 2017/8/25 10:59
*/
@Component
public
class
JwtTokenUtil
{
/**
* 获取用户名从token中
*/
public
static
String
getUsernameFromToken
(
String
token
)
{
return
getClaimFromToken
(
token
).
getSubject
();
}
/**
* 获取jwt发布时间
*/
public
static
Date
getIssuedAtDateFromToken
(
String
token
)
{
return
getClaimFromToken
(
token
).
getIssuedAt
();
}
/**
* 获取jwt失效时间
*/
public
static
Date
getExpirationDateFromToken
(
String
token
)
{
return
getClaimFromToken
(
token
).
getExpiration
();
}
/**
* 获取jwt接收者
*/
public
static
String
getAudienceFromToken
(
String
token
)
{
return
getClaimFromToken
(
token
).
getAudience
();
}
/**
* 获取私有的jwt claim
*/
public
static
String
getPrivateClaimFromToken
(
String
token
,
String
key
)
{
return
getClaimFromToken
(
token
).
get
(
key
).
toString
();
}
/**
* 获取jwt的payload部分
*/
public
static
Claims
getClaimFromToken
(
String
token
)
{
return
Jwts
.
parser
()
.
setSigningKey
(
JwtConstants
.
SECRET
)
.
parseClaimsJws
(
token
)
.
getBody
();
}
/**
* 解析token是否正确,不正确会报异常<br>
*/
public
static
void
parseToken
(
String
token
)
throws
JwtException
{
Jwts
.
parser
().
setSigningKey
(
JwtConstants
.
SECRET
).
parseClaimsJws
(
token
).
getBody
();
}
/**
* <pre>
* 验证token是否失效
* true:过期 false:没过期
* </pre>
*/
public
static
Boolean
isTokenExpired
(
String
token
)
{
try
{
final
Date
expiration
=
getExpirationDateFromToken
(
token
);
return
expiration
.
before
(
new
Date
());
}
catch
(
ExpiredJwtException
expiredJwtException
)
{
return
true
;
}
}
/**
* 生成token(通过用户名和签名时候用的随机数)
*/
public
static
String
generateToken
(
String
userName
,
String
randomKey
)
{
Map
<
String
,
Object
>
claims
=
new
HashMap
<>();
return
doGenerateToken
(
claims
,
userName
);
}
/**
* 生成token
*/
private
static
String
doGenerateToken
(
Map
<
String
,
Object
>
claims
,
String
subject
)
{
final
Date
createdDate
=
new
Date
();
final
Date
expirationDate
=
new
Date
(
createdDate
.
getTime
()
+
JwtConstants
.
EXPIRATION
*
1000
);
return
Jwts
.
builder
()
.
setClaims
(
claims
)
.
setSubject
(
subject
)
.
setIssuedAt
(
createdDate
)
.
setExpiration
(
expirationDate
)
.
signWith
(
SignatureAlgorithm
.
HS512
,
JwtConstants
.
SECRET
)
.
compact
();
}
/**
* 获取混淆MD5签名用的随机字符串
*/
public
static
String
getRandomKey
()
{
return
ToolUtil
.
getRandomString
(
6
);
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment