Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Y
yudao-cloud
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
hblj
yudao-cloud
Commits
6a4b6fe6
提交
6a4b6fe6
authored
7月 04, 2020
作者:
YunaiV
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
创建 mall-spring-boot-starter-security-admin 模块,用于管理员的认证拦截器
上级
93c64689
隐藏空白字符变更
内嵌
并排
正在显示
22 个修改的文件
包含
134 行增加
和
464 行删除
+134
-464
pom.xml
common/mall-spring-boot-starter-security-admin/pom.xml
+7
-2
AdminSecurityAutoConfiguration.java
...security/admin/config/AdminSecurityAutoConfiguration.java
+6
-35
AdminSecurityContext.java
...all/security/admin/core/context/AdminSecurityContext.java
+1
-5
AdminSecurityContextHolder.java
...curity/admin/core/context/AdminSecurityContextHolder.java
+1
-5
AdminDemoInterceptor.java
...security/admin/core/interceptor/AdminDemoInterceptor.java
+5
-5
AdminSecurityInterceptor.java
...rity/admin/core/interceptor/AdminSecurityInterceptor.java
+94
-0
spring.factories
...curity-admin/src/main/resources/META-INF/spring.factories
+1
-1
UserSecurityInterceptor.java
...curity/user/core/interceptor/UserSecurityInterceptor.java
+8
-3
UserSecurityContext.java
...coder/mall/security/core/context/UserSecurityContext.java
+0
-18
UserSecurityContextHolder.java
...mall/security/core/context/UserSecurityContextHolder.java
+0
-30
AccountAuthInterceptor.java
...all/security/core/interceptor/AccountAuthInterceptor.java
+0
-111
AdminSecurityInterceptor.java
...l/security/core/interceptor/AdminSecurityInterceptor.java
+0
-50
UserSecurityInterceptor.java
...ll/security/core/interceptor/UserSecurityInterceptor.java
+0
-48
pom.xml
common/pom.xml
+1
-1
pom.xml
mall-dependencies/pom.xml
+2
-2
pom.xml
management-web-app/pom.xml
+5
-0
AdminPassportController.java
...ementweb/controller/passport/AdminPassportController.java
+3
-2
DatabaseConfiguration.java
...n/iocoder/mall/user/biz/config/DatabaseConfiguration.java
+0
-14
ServiceExceptionConfiguration.java
...r/mall/user/biz/config/ServiceExceptionConfiguration.java
+0
-27
UserAccessLogDO.java
.../cn/iocoder/mall/user/biz/dataobject/UserAccessLogDO.java
+0
-55
UserDO.java
...main/java/cn/iocoder/mall/user/biz/dataobject/UserDO.java
+0
-41
UserLoginLogDO.java
...a/cn/iocoder/mall/user/biz/dataobject/UserLoginLogDO.java
+0
-9
没有找到文件。
common/mall-spring-boot-starter-security/pom.xml
→
common/mall-spring-boot-starter-security
-admin
/pom.xml
浏览文件 @
6a4b6fe6
...
...
@@ -9,13 +9,13 @@
</parent>
<modelVersion>
4.0.0
</modelVersion>
<artifactId>
mall-spring-boot-starter-security
</artifactId>
<artifactId>
mall-spring-boot-starter-security
-admin
</artifactId>
<dependencies>
<!-- Mall 相关 -->
<dependency>
<groupId>
cn.iocoder.mall
</groupId>
<artifactId>
system-
rpc
-api
</artifactId>
<artifactId>
system-
service
-api
</artifactId>
<version>
1.0-SNAPSHOT
</version>
</dependency>
...
...
@@ -33,6 +33,11 @@
<version>
1.0-SNAPSHOT
</version>
</dependency>
<dependency>
<groupId>
cn.iocoder.mall
</groupId>
<artifactId>
mall-security-annotations
</artifactId>
</dependency>
<!-- RPC 相关 -->
<dependency>
<groupId>
org.apache.dubbo
</groupId>
...
...
common/mall-spring-boot-starter-security
/src/main/java/cn/iocoder/mall/security/config/Commo
nSecurityAutoConfiguration.java
→
common/mall-spring-boot-starter-security
-admin/src/main/java/cn/iocoder/mall/security/admin/config/Admi
nSecurityAutoConfiguration.java
浏览文件 @
6a4b6fe6
package
cn
.
iocoder
.
mall
.
security
.
config
;
package
cn
.
iocoder
.
mall
.
security
.
admin
.
config
;
import
cn.iocoder.mall.security.core.interceptor.AccountAuthInterceptor
;
import
cn.iocoder.mall.security.core.interceptor.AdminDemoInterceptor
;
import
cn.iocoder.mall.security.core.interceptor.AdminSecurityInterceptor
;
import
cn.iocoder.mall.security.core.interceptor.UserSecurityInterceptor
;
import
cn.iocoder.mall.security.admin.core.interceptor.AdminDemoInterceptor
;
import
cn.iocoder.mall.security.admin.core.interceptor.AdminSecurityInterceptor
;
import
cn.iocoder.mall.web.config.CommonWebAutoConfiguration
;
import
cn.iocoder.mall.web.core.constant.CommonMallConstants
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.boot.autoconfigure.AutoConfigureAfter
;
...
...
@@ -18,31 +15,17 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@AutoConfigureAfter
(
CommonWebAutoConfiguration
.
class
)
// 在 CommonWebAutoConfiguration 之后自动配置,保证过滤器的顺序
@ConditionalOnWebApplication
(
type
=
ConditionalOnWebApplication
.
Type
.
SERVLET
)
public
class
Commo
nSecurityAutoConfiguration
implements
WebMvcConfigurer
{
public
class
Admi
nSecurityAutoConfiguration
implements
WebMvcConfigurer
{
private
Logger
logger
=
LoggerFactory
.
getLogger
(
getClass
());
// ========== 拦截器相关 ==========
@Bean
public
AccountAuthInterceptor
adminAccountAuthInterceptor
()
{
return
new
AccountAuthInterceptor
(
true
);
}
@Bean
public
AccountAuthInterceptor
userAccountAuthInterceptor
()
{
return
new
AccountAuthInterceptor
(
false
);
}
@Bean
public
AdminSecurityInterceptor
adminSecurityInterceptor
()
{
return
new
AdminSecurityInterceptor
();
}
@Bean
public
UserSecurityInterceptor
userSecurityInterceptor
()
{
return
new
UserSecurityInterceptor
();
}
@Bean
public
AdminDemoInterceptor
adminDemoInterceptor
()
{
return
new
AdminDemoInterceptor
();
...
...
@@ -50,23 +33,11 @@ public class CommonSecurityAutoConfiguration implements WebMvcConfigurer {
@Override
public
void
addInterceptors
(
InterceptorRegistry
registry
)
{
// AccountAuthInterceptor 拦截器
registry
.
addInterceptor
(
this
.
userAccountAuthInterceptor
())
.
addPathPatterns
(
CommonMallConstants
.
ROOT_PATH_USER
+
"/**"
);
registry
.
addInterceptor
(
this
.
adminAccountAuthInterceptor
())
.
addPathPatterns
(
CommonMallConstants
.
ROOT_PATH_ADMIN
+
"/**"
);
logger
.
info
(
"[addInterceptors][加载 AccountAuthInterceptor 拦截器完成]"
);
// AdminSecurityInterceptor 拦截器
registry
.
addInterceptor
(
this
.
adminSecurityInterceptor
())
.
addPathPatterns
(
CommonMallConstants
.
ROOT_PATH_ADMIN
+
"/**"
);
registry
.
addInterceptor
(
this
.
adminSecurityInterceptor
());
logger
.
info
(
"[addInterceptors][加载 AdminSecurityInterceptor 拦截器完成]"
);
// UserSecurityInterceptor 拦截器
registry
.
addInterceptor
(
this
.
userAccountAuthInterceptor
())
.
addPathPatterns
(
CommonMallConstants
.
ROOT_PATH_USER
+
"/**"
);
logger
.
info
(
"[addInterceptors][加载 UserSecurityInterceptor 拦截器完成]"
);
// AdminDemoInterceptor 拦截器
registry
.
addInterceptor
(
this
.
adminDemoInterceptor
())
.
addPathPatterns
(
CommonMallConstants
.
ROOT_PATH_ADMIN
+
"/**"
);
registry
.
addInterceptor
(
this
.
adminDemoInterceptor
());
logger
.
info
(
"[addInterceptors][加载 AdminDemoInterceptor 拦截器完成]"
);
}
...
...
common/mall-spring-boot-starter-security
/src/main/java/cn/iocoder/mall/security
/core/context/AdminSecurityContext.java
→
common/mall-spring-boot-starter-security
-admin/src/main/java/cn/iocoder/mall/security/admin
/core/context/AdminSecurityContext.java
浏览文件 @
6a4b6fe6
package
cn
.
iocoder
.
mall
.
security
.
core
.
context
;
package
cn
.
iocoder
.
mall
.
security
.
admin
.
core
.
context
;
import
lombok.Data
;
import
lombok.experimental.Accessors
;
...
...
@@ -14,9 +14,5 @@ public class AdminSecurityContext {
* 管理员编号
*/
private
Integer
adminId
;
/**
* 账号编号
*/
private
Integer
accountId
;
}
common/mall-spring-boot-starter-security
/src/main/java/cn/iocoder/mall/security
/core/context/AdminSecurityContextHolder.java
→
common/mall-spring-boot-starter-security
-admin/src/main/java/cn/iocoder/mall/security/admin
/core/context/AdminSecurityContextHolder.java
浏览文件 @
6a4b6fe6
package
cn
.
iocoder
.
mall
.
security
.
core
.
context
;
package
cn
.
iocoder
.
mall
.
security
.
admin
.
core
.
context
;
/**
* {@link AdminSecurityContext} Holder
...
...
@@ -31,8 +31,4 @@ public class AdminSecurityContextHolder {
return
getContext
().
getAdminId
();
}
public
static
Integer
getAccountId
()
{
return
getContext
().
getAccountId
();
}
}
common/mall-spring-boot-starter-security
/src/main/java/cn/iocoder/mall/security
/core/interceptor/AdminDemoInterceptor.java
→
common/mall-spring-boot-starter-security
-admin/src/main/java/cn/iocoder/mall/security/admin
/core/interceptor/AdminDemoInterceptor.java
浏览文件 @
6a4b6fe6
package
cn
.
iocoder
.
mall
.
security
.
core
.
interceptor
;
package
cn
.
iocoder
.
mall
.
security
.
admin
.
core
.
interceptor
;
import
cn.iocoder.common.framework.util.ServiceExceptionUtil
;
import
cn.iocoder.mall.security.core.context.AdminSecurityContextHolder
;
import
cn.iocoder.mall.system
.biz
.enums.SystemErrorCodeEnum
;
import
cn.iocoder.mall.security.
admin.
core.context.AdminSecurityContextHolder
;
import
cn.iocoder.mall.system
service
.enums.SystemErrorCodeEnum
;
import
org.springframework.http.HttpMethod
;
import
org.springframework.web.servlet.handler.HandlerInterceptorAdapter
;
...
...
@@ -20,9 +20,9 @@ public class AdminDemoInterceptor extends HandlerInterceptorAdapter {
@Override
public
boolean
preHandle
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
)
{
// 当 Admin 编号等于 0 时,约定为演示账号
if
(
Objects
.
equals
(
AdminSecurityContextHolder
.
get
Context
().
get
AdminId
(),
0
)
if
(
Objects
.
equals
(
AdminSecurityContextHolder
.
getAdminId
(),
0
)
&&
request
.
getMethod
().
equalsIgnoreCase
(
HttpMethod
.
POST
.
toString
()))
{
throw
ServiceExceptionUtil
.
exception
(
SystemErrorCodeEnum
.
AUTHORIZATION_DEMO_PERMISSION_DENY
.
getCode
()
);
throw
ServiceExceptionUtil
.
exception
(
SystemErrorCodeEnum
.
AUTHORIZATION_DEMO_PERMISSION_DENY
);
}
return
true
;
}
...
...
common/mall-spring-boot-starter-security-admin/src/main/java/cn/iocoder/mall/security/admin/core/interceptor/AdminSecurityInterceptor.java
0 → 100644
浏览文件 @
6a4b6fe6
package
cn
.
iocoder
.
mall
.
security
.
admin
.
core
.
interceptor
;
import
cn.iocoder.common.framework.enums.UserTypeEnum
;
import
cn.iocoder.common.framework.util.CollectionUtil
;
import
cn.iocoder.common.framework.util.HttpUtil
;
import
cn.iocoder.common.framework.util.ServiceExceptionUtil
;
import
cn.iocoder.common.framework.vo.CommonResult
;
import
cn.iocoder.mall.security.admin.core.context.AdminSecurityContext
;
import
cn.iocoder.mall.security.admin.core.context.AdminSecurityContextHolder
;
import
cn.iocoder.mall.systemservice.enums.SystemErrorCodeEnum
;
import
cn.iocoder.mall.systemservice.rpc.oauth.OAuth2Rpc
;
import
cn.iocoder.mall.systemservice.rpc.oauth.vo.OAuth2AccessTokenVO
;
import
cn.iocoder.mall.web.core.util.CommonWebUtil
;
import
cn.iocoder.security.annotations.RequiresNone
;
import
cn.iocoder.security.annotations.RequiresPermissions
;
import
org.apache.dubbo.config.annotation.Reference
;
import
org.springframework.web.method.HandlerMethod
;
import
org.springframework.web.servlet.handler.HandlerInterceptorAdapter
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
static
cn
.
iocoder
.
mall
.
systemservice
.
enums
.
SystemErrorCodeEnum
.
OAUTH_USER_TYPE_ERROR
;
public
class
AdminSecurityInterceptor
extends
HandlerInterceptorAdapter
{
@Reference
(
validation
=
"true"
,
version
=
"${dubbo.consumer.OAuth2Rpc.version}"
)
private
OAuth2Rpc
oauth2Rpc
;
@Override
public
boolean
preHandle
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
)
{
// 获得访问令牌
Integer
adminId
=
this
.
obtainAdminId
(
request
);
// 校验认证
this
.
checkAuthentication
((
HandlerMethod
)
handler
,
adminId
);
// 校验权限
this
.
checkPermission
((
HandlerMethod
)
handler
,
adminId
);
return
true
;
}
private
Integer
obtainAdminId
(
HttpServletRequest
request
)
{
String
accessToken
=
HttpUtil
.
obtainAuthorization
(
request
);
Integer
adminId
=
null
;
if
(
accessToken
!=
null
)
{
CommonResult
<
OAuth2AccessTokenVO
>
checkAccessTokenResult
=
oauth2Rpc
.
checkAccessToken
(
accessToken
);
checkAccessTokenResult
.
checkError
();
// 校验用户类型正确
if
(!
UserTypeEnum
.
ADMIN
.
getValue
().
equals
(
checkAccessTokenResult
.
getData
().
getUserType
()))
{
throw
ServiceExceptionUtil
.
exception
(
OAUTH_USER_TYPE_ERROR
);
}
// 获得用户编号
adminId
=
checkAccessTokenResult
.
getData
().
getUserId
();
// 设置到 Request 中
CommonWebUtil
.
setUserId
(
request
,
adminId
);
CommonWebUtil
.
setUserType
(
request
,
UserTypeEnum
.
ADMIN
.
getValue
());
// 设置到
AdminSecurityContext
adminSecurityContext
=
new
AdminSecurityContext
().
setAdminId
(
adminId
);
AdminSecurityContextHolder
.
setContext
(
adminSecurityContext
);
}
return
adminId
;
}
private
void
checkAuthentication
(
HandlerMethod
handlerMethod
,
Integer
adminId
)
{
boolean
requiresAuthenticate
=
!
handlerMethod
.
hasMethodAnnotation
(
RequiresNone
.
class
);
// 对于 ADMIN 来说,默认需登录
if
(
requiresAuthenticate
&&
adminId
==
null
)
{
throw
ServiceExceptionUtil
.
exception
(
SystemErrorCodeEnum
.
OAUTH2_NOT_AUTHENTICATION
);
}
}
private
void
checkPermission
(
HandlerMethod
handlerMethod
,
Integer
accountId
)
{
RequiresPermissions
requiresPermissions
=
handlerMethod
.
getMethodAnnotation
(
RequiresPermissions
.
class
);
if
(
requiresPermissions
==
null
)
{
return
;
}
String
[]
permissions
=
requiresPermissions
.
value
();
if
(
CollectionUtil
.
isEmpty
(
permissions
))
{
return
;
}
// 权限验证 TODO 待完成
// AuthorizationCheckPermissionsRequest authorizationCheckPermissionsRequest = new AuthorizationCheckPermissionsRequest()
// .setAccountId(accountId).setPermissions(Arrays.asList(permissions));
// CommonResult<Boolean> authorizationCheckPermissionsResult = authorizationRPC.checkPermissions(authorizationCheckPermissionsRequest);
// if (authorizationCheckPermissionsResult.isError()) { // TODO 有一个问题点,假设 token 认证失败,但是该 url 是无需认证的,是不是一样能够执行过去?
// throw ServiceExceptionUtil.exception(authorizationCheckPermissionsResult);
// }
}
@Override
public
void
afterCompletion
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
,
Exception
ex
)
{
// 清空 SecurityContext
AdminSecurityContextHolder
.
clear
();
}
}
common/mall-spring-boot-starter-security/src/main/resources/META-INF/spring.factories
→
common/mall-spring-boot-starter-security
-admin
/src/main/resources/META-INF/spring.factories
浏览文件 @
6a4b6fe6
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.iocoder.mall.security.
config.Commo
nSecurityAutoConfiguration
cn.iocoder.mall.security.
admin.config.Admi
nSecurityAutoConfiguration
common/mall-spring-boot-starter-security-user/src/main/java/cn/iocoder/mall/security/user/core/interceptor/UserSecurityInterceptor.java
浏览文件 @
6a4b6fe6
...
...
@@ -29,6 +29,13 @@ public class UserSecurityInterceptor extends HandlerInterceptorAdapter {
@Override
public
boolean
preHandle
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
)
{
// 获得访问令牌
Integer
userId
=
this
.
obtainUserId
(
request
);
// 校验认证
this
.
checkAuthentication
((
HandlerMethod
)
handler
,
userId
);
return
true
;
}
private
Integer
obtainUserId
(
HttpServletRequest
request
)
{
String
accessToken
=
HttpUtil
.
obtainAuthorization
(
request
);
Integer
userId
=
null
;
if
(
accessToken
!=
null
)
{
...
...
@@ -47,9 +54,7 @@ public class UserSecurityInterceptor extends HandlerInterceptorAdapter {
UserSecurityContext
userSecurityContext
=
new
UserSecurityContext
().
setUserId
(
userId
);
UserSecurityContextHolder
.
setContext
(
userSecurityContext
);
}
// 校验认证
this
.
checkAuthentication
((
HandlerMethod
)
handler
,
userId
);
return
true
;
return
userId
;
}
private
void
checkAuthentication
(
HandlerMethod
handlerMethod
,
Integer
userId
)
{
...
...
common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/context/UserSecurityContext.java
deleted
100644 → 0
浏览文件 @
93c64689
package
cn
.
iocoder
.
mall
.
security
.
core
.
context
;
import
lombok.Data
;
import
lombok.experimental.Accessors
;
/**
* User Security 上下文
*/
@Data
@Accessors
(
chain
=
true
)
public
class
UserSecurityContext
{
/**
* 用户编号
*/
private
Integer
userId
;
}
common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/context/UserSecurityContextHolder.java
deleted
100644 → 0
浏览文件 @
93c64689
package
cn
.
iocoder
.
mall
.
security
.
core
.
context
;
/**
* {@link UserSecurityContext} Holder
*
* 参考 spring security 的 ThreadLocalSecurityContextHolderStrategy 类,简单实现。
*/
public
class
UserSecurityContextHolder
{
private
static
final
ThreadLocal
<
UserSecurityContext
>
SECURITY_CONTEXT
=
new
ThreadLocal
<
UserSecurityContext
>();
public
static
void
setContext
(
UserSecurityContext
context
)
{
SECURITY_CONTEXT
.
set
(
context
);
}
public
static
UserSecurityContext
getContext
()
{
UserSecurityContext
ctx
=
SECURITY_CONTEXT
.
get
();
// 为空时,设置一个空的进去
if
(
ctx
==
null
)
{
ctx
=
new
UserSecurityContext
();
SECURITY_CONTEXT
.
set
(
ctx
);
}
return
ctx
;
}
public
static
void
clear
()
{
SECURITY_CONTEXT
.
remove
();
}
}
common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/interceptor/AccountAuthInterceptor.java
deleted
100644 → 0
浏览文件 @
93c64689
package
cn
.
iocoder
.
mall
.
security
.
core
.
interceptor
;
import
cn.iocoder.common.framework.util.CollectionUtil
;
import
cn.iocoder.common.framework.util.HttpUtil
;
import
cn.iocoder.common.framework.util.ServiceExceptionUtil
;
import
cn.iocoder.common.framework.vo.CommonResult
;
import
cn.iocoder.mall.security.core.annotation.RequiresAuthenticate
;
import
cn.iocoder.mall.security.core.annotation.RequiresNone
;
import
cn.iocoder.mall.security.core.annotation.RequiresPermissions
;
import
cn.iocoder.mall.system.biz.enums.SystemErrorCodeEnum
;
import
cn.iocoder.mall.system.rpc.api.authorization.AuthorizationRPC
;
import
cn.iocoder.mall.system.rpc.api.oauth2.OAuth2RPC
;
import
cn.iocoder.mall.system.rpc.request.authorization.AuthorizationCheckPermissionsRequest
;
import
cn.iocoder.mall.system.rpc.request.oauth2.OAuth2AccessTokenAuthenticateRequest
;
import
cn.iocoder.mall.system.rpc.response.oauth2.OAuth2AccessTokenResponse
;
import
cn.iocoder.mall.web.core.util.CommonWebUtil
;
import
org.apache.dubbo.config.annotation.Reference
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.util.StringUtils
;
import
org.springframework.web.method.HandlerMethod
;
import
org.springframework.web.servlet.handler.HandlerInterceptorAdapter
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.util.Arrays
;
public
class
AccountAuthInterceptor
extends
HandlerInterceptorAdapter
{
private
Logger
logger
=
LoggerFactory
.
getLogger
(
getClass
());
@Reference
(
validation
=
"true"
,
version
=
"${dubbo.consumer.OAuth2RPC.version}"
)
private
OAuth2RPC
oauth2RPC
;
@Reference
(
validation
=
"true"
,
version
=
"${dubbo.consumer.AuthorizationRPC.version}"
)
private
AuthorizationRPC
authorizationRPC
;
/**
* 是否默认要求认证
*
* 针对 /users/** 接口,一般默认不要求认证,因为面向用户的接口,往往不需要登陆即可访问
* 针对 /admins/** 接口,一般默认要求认证,因为面向管理员的接口,往往是内部需要更严格的安全控制
*/
private
final
boolean
defaultRequiresAuthenticate
;
public
AccountAuthInterceptor
(
boolean
defaultRequiresAuthenticate
)
{
this
.
defaultRequiresAuthenticate
=
defaultRequiresAuthenticate
;
}
@Override
public
boolean
preHandle
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
)
{
// 1. 进行认证
Integer
accountId
=
this
.
obtainAccount
(
request
);
// 2. 进行鉴权
HandlerMethod
handlerMethod
=
(
HandlerMethod
)
handler
;
// 判断是否需要认证
this
.
checkAuthenticate
(
handlerMethod
,
accountId
);
// 判断是否需要权限
this
.
checkPermission
(
handlerMethod
,
accountId
);
return
true
;
}
private
Integer
obtainAccount
(
HttpServletRequest
request
)
{
String
accessToken
=
HttpUtil
.
obtainAuthorization
(
request
);
// 获得访问令牌
if
(!
StringUtils
.
hasText
(
accessToken
))
{
// 如果未传递,则不进行认证
return
null
;
}
// 执行认证
OAuth2AccessTokenAuthenticateRequest
oauth2AccessTokenAuthenticateRequest
=
new
OAuth2AccessTokenAuthenticateRequest
()
.
setAccessToken
(
accessToken
).
setIp
(
HttpUtil
.
getIp
(
request
));
CommonResult
<
OAuth2AccessTokenResponse
>
oauth2AccessTokenResult
=
oauth2RPC
.
authenticate
(
oauth2AccessTokenAuthenticateRequest
);
if
(
oauth2AccessTokenResult
.
isError
())
{
// TODO 有一个问题点,假设 token 认证失败,但是该 url 是无需认证的,是不是一样能够执行过去?
throw
ServiceExceptionUtil
.
exception
(
oauth2AccessTokenResult
);
}
// 设置账号编号
Integer
accountId
=
oauth2AccessTokenResult
.
getData
().
getAccountId
();
CommonWebUtil
.
setUserId
(
request
,
accountId
);
return
accountId
;
}
private
void
checkAuthenticate
(
HandlerMethod
handlerMethod
,
Integer
accountId
)
{
boolean
requiresAuthenticate
=
defaultRequiresAuthenticate
;
if
(
handlerMethod
.
hasMethodAnnotation
(
RequiresAuthenticate
.
class
)
||
handlerMethod
.
hasMethodAnnotation
(
RequiresPermissions
.
class
))
{
// 如果需要权限验证,也认为需要认证
requiresAuthenticate
=
true
;
}
else
if
(
handlerMethod
.
hasMethodAnnotation
(
RequiresNone
.
class
))
{
requiresAuthenticate
=
false
;
}
if
(
requiresAuthenticate
&&
accountId
==
null
)
{
throw
ServiceExceptionUtil
.
exception
(
SystemErrorCodeEnum
.
OAUTH2_NOT_AUTHENTICATE
);
}
}
private
void
checkPermission
(
HandlerMethod
handlerMethod
,
Integer
accountId
)
{
RequiresPermissions
requiresPermissions
=
handlerMethod
.
getMethodAnnotation
(
RequiresPermissions
.
class
);
if
(
requiresPermissions
==
null
)
{
return
;
}
String
[]
permissions
=
requiresPermissions
.
value
();
if
(
CollectionUtil
.
isEmpty
(
permissions
))
{
return
;
}
// 权限验证
AuthorizationCheckPermissionsRequest
authorizationCheckPermissionsRequest
=
new
AuthorizationCheckPermissionsRequest
()
.
setAccountId
(
accountId
).
setPermissions
(
Arrays
.
asList
(
permissions
));
CommonResult
<
Boolean
>
authorizationCheckPermissionsResult
=
authorizationRPC
.
checkPermissions
(
authorizationCheckPermissionsRequest
);
if
(
authorizationCheckPermissionsResult
.
isError
())
{
// TODO 有一个问题点,假设 token 认证失败,但是该 url 是无需认证的,是不是一样能够执行过去?
throw
ServiceExceptionUtil
.
exception
(
authorizationCheckPermissionsResult
);
}
}
}
common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/interceptor/AdminSecurityInterceptor.java
deleted
100644 → 0
浏览文件 @
93c64689
package
cn
.
iocoder
.
mall
.
security
.
core
.
interceptor
;
import
cn.iocoder.common.framework.util.ServiceExceptionUtil
;
import
cn.iocoder.common.framework.vo.CommonResult
;
import
cn.iocoder.mall.security.core.context.AdminSecurityContext
;
import
cn.iocoder.mall.security.core.context.AdminSecurityContextHolder
;
import
cn.iocoder.mall.system.rpc.api.admin.AdminRPC
;
import
cn.iocoder.mall.system.rpc.response.admin.AdminResponse
;
import
cn.iocoder.mall.web.core.util.CommonWebUtil
;
import
org.apache.dubbo.config.annotation.Reference
;
import
org.springframework.web.servlet.handler.HandlerInterceptorAdapter
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
static
cn
.
iocoder
.
mall
.
system
.
biz
.
enums
.
SystemErrorCodeEnum
.
ADMIN_NOT_FOUND
;
public
class
AdminSecurityInterceptor
extends
HandlerInterceptorAdapter
{
@Reference
(
validation
=
"true"
,
version
=
"${dubbo.consumer.AdminRPC.version}"
)
private
AdminRPC
adminRPC
;
@Override
public
boolean
preHandle
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
)
{
Integer
accountId
=
CommonWebUtil
.
getUserId
(
request
);
if
(
accountId
!=
null
)
{
// 获得 Admin 信息
CommonResult
<
AdminResponse
>
adminResult
=
adminRPC
.
getAdminByAccountId
(
accountId
);
if
(
adminResult
.
isError
())
{
throw
ServiceExceptionUtil
.
exception
(
adminResult
);
}
if
(
adminResult
.
getData
()
==
null
)
{
throw
ServiceExceptionUtil
.
exception
(
ADMIN_NOT_FOUND
);
}
// 设置到 SecurityContext 中
AdminResponse
adminResponse
=
adminResult
.
getData
();
AdminSecurityContext
context
=
new
AdminSecurityContext
().
setAdminId
(
adminResponse
.
getId
())
.
setAccountId
(
accountId
);
AdminSecurityContextHolder
.
setContext
(
context
);
}
return
true
;
}
@Override
public
void
afterCompletion
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
,
Exception
ex
)
{
// 清空 SecurityContext
AdminSecurityContextHolder
.
clear
();
}
}
common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/interceptor/UserSecurityInterceptor.java
deleted
100644 → 0
浏览文件 @
93c64689
package
cn
.
iocoder
.
mall
.
security
.
core
.
interceptor
;
import
cn.iocoder.common.framework.util.ExceptionUtil
;
import
cn.iocoder.common.framework.util.ServiceExceptionUtil
;
import
cn.iocoder.common.framework.vo.CommonResult
;
import
cn.iocoder.mall.security.core.context.UserSecurityContext
;
import
cn.iocoder.mall.security.core.context.UserSecurityContextHolder
;
import
cn.iocoder.mall.system.rpc.api.user.UserRPC
;
import
cn.iocoder.mall.system.rpc.response.user.UserResponse
;
import
cn.iocoder.mall.web.core.util.CommonWebUtil
;
import
org.apache.dubbo.config.annotation.Reference
;
import
org.springframework.web.servlet.handler.HandlerInterceptorAdapter
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
public
class
UserSecurityInterceptor
extends
HandlerInterceptorAdapter
{
@Reference
(
validation
=
"true"
,
version
=
"${dubbo.consumer.UserRPC.version}"
)
private
UserRPC
userRPC
;
@Override
public
boolean
preHandle
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
)
{
Integer
accountId
=
CommonWebUtil
.
getUserId
(
request
);
if
(
accountId
!=
null
)
{
// 获得 Admin 信息
CommonResult
<
UserResponse
>
userResult
=
userRPC
.
getUserByAccountId
(
accountId
);
if
(
userResult
.
isError
())
{
throw
ServiceExceptionUtil
.
exception
(
userResult
);
}
if
(
userResult
.
getData
()
==
null
)
{
throw
ExceptionUtil
.
getServiceException
(
null
);
// TODO 需要完善
}
// 设置到 SecurityContext 中
UserResponse
userResponse
=
userResult
.
getData
();
UserSecurityContext
context
=
new
UserSecurityContext
().
setUserId
(
userResponse
.
getId
());
UserSecurityContextHolder
.
setContext
(
context
);
}
return
true
;
}
@Override
public
void
afterCompletion
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
,
Exception
ex
)
{
// 清空 SecurityContext
UserSecurityContextHolder
.
clear
();
}
}
common/pom.xml
浏览文件 @
6a4b6fe6
...
...
@@ -17,7 +17,7 @@
<module>
mall-spring-boot-starter-swagger
</module>
<module>
mall-spring-boot-starter-web
</module>
<module>
mall-security-annotations
</module>
<module>
mall-spring-boot-starter-security
</module>
<module>
mall-spring-boot-starter-security
-admin
</module>
<module>
mall-spring-boot-starter-security-user
</module>
<module>
mall-spring-boot-starter-mybatis
</module>
</modules>
...
...
mall-dependencies/pom.xml
浏览文件 @
6a4b6fe6
...
...
@@ -147,12 +147,12 @@
</dependency>
<dependency>
<groupId>
cn.iocoder.mall
</groupId>
<artifactId>
mall-spring-boot-starter-security
</artifactId>
<artifactId>
mall-spring-boot-starter-security
-user
</artifactId>
<version>
1.0-SNAPSHOT
</version>
</dependency>
<dependency>
<groupId>
cn.iocoder.mall
</groupId>
<artifactId>
mall-spring-boot-starter-security-
user
</artifactId>
<artifactId>
mall-spring-boot-starter-security-
admin
</artifactId>
<version>
1.0-SNAPSHOT
</version>
</dependency>
...
...
management-web-app/pom.xml
浏览文件 @
6a4b6fe6
...
...
@@ -37,6 +37,11 @@
<artifactId>
mall-spring-boot-starter-swagger
</artifactId>
</dependency>
<dependency>
<groupId>
cn.iocoder.mall
</groupId>
<artifactId>
mall-spring-boot-starter-security-admin
</artifactId>
</dependency>
<!-- RPC 相关 -->
<dependency>
<groupId>
com.alibaba.cloud
</groupId>
...
...
management-web-app/src/main/java/cn/iocoder/mall/managementweb/controller/passport/AdminPassportController.java
浏览文件 @
6a4b6fe6
...
...
@@ -5,6 +5,7 @@ import cn.iocoder.common.framework.vo.CommonResult;
import
cn.iocoder.mall.managementweb.controller.passport.dto.AdminPassportLoginDTO
;
import
cn.iocoder.mall.managementweb.controller.passport.vo.AdminPassportVO
;
import
cn.iocoder.mall.managementweb.manager.admin.AdminPassportManager
;
import
cn.iocoder.security.annotations.RequiresNone
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
org.springframework.beans.factory.annotation.Autowired
;
...
...
@@ -24,9 +25,9 @@ public class AdminPassportController {
@Autowired
private
AdminPassportManager
adminPassportManager
;
@PostMapping
(
"/login"
)
@ApiOperation
(
"账号密码登陆"
)
// @RequiresNone TODO 晚点加上
@PostMapping
(
"/login"
)
@RequiresNone
public
CommonResult
<
AdminPassportVO
>
login
(
AdminPassportLoginDTO
loginDTO
,
HttpServletRequest
request
)
{
return
success
(
adminPassportManager
.
login
(
loginDTO
,
HttpUtil
.
getIp
(
request
)));
...
...
user/user-service-impl/src/main/java/cn/iocoder/mall/user/biz/config/DatabaseConfiguration.java
deleted
100644 → 0
浏览文件 @
93c64689
package
cn
.
iocoder
.
mall
.
user
.
biz
.
config
;
import
org.mybatis.spring.annotation.MapperScan
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.transaction.annotation.EnableTransactionManagement
;
@Configuration
@MapperScan
(
"cn.iocoder.mall.user.biz.dao"
)
// 扫描对应的 Mapper 接口
@EnableTransactionManagement
(
proxyTargetClass
=
true
)
// 启动事务管理。为什么使用 proxyTargetClass 参数,参见 https://blog.csdn.net/huang_550/article/details/76492600
public
class
DatabaseConfiguration
{
// 数据源,使用 Druid
}
user/user-service-impl/src/main/java/cn/iocoder/mall/user/biz/config/ServiceExceptionConfiguration.java
deleted
100644 → 0
浏览文件 @
93c64689
package
cn
.
iocoder
.
mall
.
user
.
biz
.
config
;
import
cn.iocoder.common.framework.util.ServiceExceptionUtil
;
import
cn.iocoder.mall.user.api.constant.UserErrorCodeEnum
;
import
org.springframework.boot.context.event.ApplicationReadyEvent
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.event.EventListener
;
@Configuration
public
class
ServiceExceptionConfiguration
{
@EventListener
(
ApplicationReadyEvent
.
class
)
// 可参考 https://www.cnblogs.com/ssslinppp/p/7607509.html
public
void
initMessages
()
{
// 从 service_exception_message.properties 加载错误码的方案
// Properties properties;
// try {
// properties = PropertiesLoaderUtils.loadAllProperties("classpath:service_exception_message.properties");
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
for
(
UserErrorCodeEnum
item
:
UserErrorCodeEnum
.
values
())
{
ServiceExceptionUtil
.
put
(
item
.
getCode
(),
item
.
getMessage
());
}
}
}
\ No newline at end of file
user/user-service-impl/src/main/java/cn/iocoder/mall/user/biz/dataobject/UserAccessLogDO.java
deleted
100644 → 0
浏览文件 @
93c64689
package
cn
.
iocoder
.
mall
.
user
.
biz
.
dataobject
;
import
cn.iocoder.common.framework.dataobject.DeletableDO
;
import
lombok.Data
;
import
lombok.experimental.Accessors
;
import
java.util.Date
;
/**
* 用户访问日志 DO
*/
@Data
@Accessors
(
chain
=
true
)
public
class
UserAccessLogDO
extends
DeletableDO
{
/**
* 编号
*/
private
Integer
id
;
/**
* 用户编号.
*
* 当用户编号为空时,该值为0
*/
private
Integer
userId
;
/**
* 访问地址
*/
private
String
uri
;
/**
* 参数
*/
private
String
queryString
;
/**
* http 方法
*/
private
String
method
;
/**
* userAgent
*/
private
String
userAgent
;
/**
* ip
*/
private
String
ip
;
/**
* 请求时间
*/
private
Date
startTime
;
/**
* 响应时长 -- 毫秒级
*/
private
Integer
responseTime
;
}
user/user-service-impl/src/main/java/cn/iocoder/mall/user/biz/dataobject/UserDO.java
deleted
100644 → 0
浏览文件 @
93c64689
package
cn
.
iocoder
.
mall
.
user
.
biz
.
dataobject
;
import
cn.iocoder.common.framework.dataobject.DeletableDO
;
import
lombok.Data
;
import
lombok.experimental.Accessors
;
/**
* 用户实体,存储用户基本数据。
*
* idx_mobile 唯一索引
*/
@Data
@Accessors
(
chain
=
true
)
public
class
UserDO
extends
DeletableDO
{
/**
* 用户编号
*/
private
Integer
id
;
/**
* 手机号
*/
private
String
mobile
;
/**
* 昵称
*/
private
String
nickname
;
/**
* 头像
*/
private
String
avatar
;
/**
* 账号状态
*
* 1 - 开启
* 2 - 禁用
*/
private
Integer
status
;
}
user/user-service-impl/src/main/java/cn/iocoder/mall/user/biz/dataobject/UserLoginLogDO.java
deleted
100644 → 0
浏览文件 @
93c64689
package
cn
.
iocoder
.
mall
.
user
.
biz
.
dataobject
;
import
lombok.Data
;
import
lombok.experimental.Accessors
;
@Data
@Accessors
(
chain
=
true
)
public
class
UserLoginLogDO
{
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论