Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
spring-microservice-exam
Project
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
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
汪想
spring-microservice-exam
Commits
b822b4d2
Commit
b822b4d2
authored
Nov 14, 2019
by
tangyi
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev'
parents
8660b235
ec73b1e7
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
45 changed files
with
734 additions
and
448 deletions
+734
-448
README.md
README.md
+1
-1
pom.xml
common/common-security/pom.xml
+6
-0
AdminAuthorization.java
...angyi/common/security/annotations/AdminAuthorization.java
+18
-0
AdminTenantTeacherAuthorization.java
...security/annotations/AdminTenantTeacherAuthorization.java
+18
-0
UserAuthorization.java
...tangyi/common/security/annotations/UserAuthorization.java
+18
-0
SecurityConstant.java
...hub/tangyi/common/security/constant/SecurityConstant.java
+0
-15
CustomUserDetailsService.java
...tangyi/common/security/core/CustomUserDetailsService.java
+6
-6
Roles.java
...n/java/com/github/tangyi/common/security/enums/Roles.java
+36
-0
CustomAuthenticationFailureEvent.java
...mmon/security/event/CustomAuthenticationFailureEvent.java
+25
-0
CustomAuthenticationSuccessEvent.java
...mmon/security/event/CustomAuthenticationSuccessEvent.java
+23
-0
CustomOauthException.java
...ngyi/common/security/exceptions/CustomOauthException.java
+0
-27
MobileAuthenticationProvider.java
.../common/security/mobile/MobileAuthenticationProvider.java
+8
-1
MobileSecurityConfigurer.java
...ngyi/common/security/mobile/MobileSecurityConfigurer.java
+5
-0
CustomOauthExceptionSerializer.java
...n/security/serializer/CustomOauthExceptionSerializer.java
+0
-40
WxAuthenticationProvider.java
...b/tangyi/common/security/wx/WxAuthenticationProvider.java
+7
-0
WxSecurityConfigurer.java
...ithub/tangyi/common/security/wx/WxSecurityConfigurer.java
+5
-0
package-lock.json
frontend/spring-microservice-exam-web/package-lock.json
+0
-0
AopConfig.java
...rc/main/java/com/github/tangyi/auth/config/AopConfig.java
+16
-0
CustomAuthorizationServerConfigurer.java
...ngyi/auth/config/CustomAuthorizationServerConfigurer.java
+3
-38
SecurityConfig.java
...in/java/com/github/tangyi/auth/config/SecurityConfig.java
+27
-1
OauthClientDetailsController.java
.../tangyi/auth/controller/OauthClientDetailsController.java
+5
-6
CustomOAuth2AccessDeniedHandler.java
...ub/tangyi/auth/error/CustomOAuth2AccessDeniedHandler.java
+48
-0
CustomOAuth2ExceptionRenderer.java
...thub/tangyi/auth/error/CustomOAuth2ExceptionRenderer.java
+106
-0
CustomTokenEndpointAuthenticationFilter.java
.../auth/filter/CustomTokenEndpointAuthenticationFilter.java
+0
-94
LoginFailureListener.java
...com/github/tangyi/auth/listener/LoginFailureListener.java
+29
-0
LoginSuccessListener.java
...com/github/tangyi/auth/listener/LoginSuccessListener.java
+103
-0
CustomUserDetailsAuthenticationProvider.java
...uth/security/CustomUserDetailsAuthenticationProvider.java
+11
-3
CustomUserDetailsServiceImpl.java
...ub/tangyi/auth/security/CustomUserDetailsServiceImpl.java
+10
-88
ValidateTenantAspect.java
...com/github/tangyi/auth/security/ValidateTenantAspect.java
+42
-0
CourseController.java
...a/com/github/tangyi/exam/controller/CourseController.java
+5
-6
ExamRecordController.java
...m/github/tangyi/exam/controller/ExamRecordController.java
+4
-62
ExaminationController.java
.../github/tangyi/exam/controller/ExaminationController.java
+5
-7
SubjectCategoryController.java
...hub/tangyi/exam/controller/SubjectCategoryController.java
+4
-5
SubjectController.java
.../com/github/tangyi/exam/controller/SubjectController.java
+7
-8
ExamRecordService.java
...ava/com/github/tangyi/exam/service/ExamRecordService.java
+47
-0
ExaminationService.java
...va/com/github/tangyi/exam/service/ExaminationService.java
+0
-1
SubjectService.java
...n/java/com/github/tangyi/exam/service/SubjectService.java
+0
-1
MenuConstant.java
...ava/com/github/tangyi/user/api/constant/MenuConstant.java
+23
-0
DeptController.java
...ava/com/github/tangyi/user/controller/DeptController.java
+4
-5
LogController.java
...java/com/github/tangyi/user/controller/LogController.java
+3
-8
MenuController.java
...ava/com/github/tangyi/user/controller/MenuController.java
+6
-7
RoleController.java
...ava/com/github/tangyi/user/controller/RoleController.java
+5
-6
UserController.java
...ava/com/github/tangyi/user/controller/UserController.java
+8
-8
MenuService.java
...main/java/com/github/tangyi/user/service/MenuService.java
+29
-4
pom.xml
pom.xml
+8
-0
No files found.
README.md
View file @
b822b4d2
...
...
@@ -46,7 +46,7 @@
| 名称 | 版本 |
| --------- | -------- |
|
`Spring Boot`
|
`2.1.
8
.RELEASE`
|
|
`Spring Boot`
|
`2.1.
9
.RELEASE`
|
|
`Spring Cloud`
|
`Greenwich.SR3`
|
# 5 系统架构
...
...
common/common-security/pom.xml
View file @
b822b4d2
...
...
@@ -35,5 +35,11 @@
<artifactId>
commons-io
</artifactId>
<version>
${commons-io.version}
</version>
</dependency>
<!-- jjwt -->
<dependency>
<groupId>
io.jsonwebtoken
</groupId>
<artifactId>
jjwt
</artifactId>
</dependency>
</dependencies>
</project>
common/common-security/src/main/java/com/github/tangyi/common/security/annotations/AdminAuthorization.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
common
.
security
.
annotations
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
java.lang.annotation.*
;
/**
* 超级管理员权限注解
*
* @author tangyi
* @date 2019/11/02 12:33
*/
@Target
({
ElementType
.
METHOD
,
ElementType
.
TYPE
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Inherited
@PreAuthorize
(
"hasRole(T(com.github.tangyi.common.security.enums.Roles).ROLE_ADMIN)"
)
public
@interface
AdminAuthorization
{
}
common/common-security/src/main/java/com/github/tangyi/common/security/annotations/AdminTenantTeacherAuthorization.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
common
.
security
.
annotations
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
java.lang.annotation.*
;
/**
* 租户或超管权限
*
* @author tangyi
* @date 2019/11/02 12:40
*/
@Target
({
ElementType
.
METHOD
,
ElementType
.
TYPE
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Inherited
@PreAuthorize
(
"hasRole(T(com.github.tangyi.common.security.enums.Roles).ROLE_ADMIN) or hasRole(T(com.github.tangyi.common.security.enums.Roles).ROLE_TENANT_ADMIN) or hasRole(T(com.github.tangyi.common.security.enums.Roles).ROLE_TEACHER)"
)
public
@interface
AdminTenantTeacherAuthorization
{
}
common/common-security/src/main/java/com/github/tangyi/common/security/annotations/UserAuthorization.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
common
.
security
.
annotations
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
java.lang.annotation.*
;
/**
* 普通用户权限
*
* @author tangyi
* @date 2019/11/02 12:44
*/
@Target
({
ElementType
.
METHOD
,
ElementType
.
TYPE
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Inherited
@PreAuthorize
(
"hasRole(T(com.github.tangyi.common.security.enums.Roles).ROLE_USER)"
)
public
@interface
UserAuthorization
{
}
common/common-security/src/main/java/com/github/tangyi/common/security/constant/SecurityConstant.java
View file @
b822b4d2
...
...
@@ -7,16 +7,6 @@ package com.github.tangyi.common.security.constant;
public
class
SecurityConstant
{
/**
* 基础角色
*/
public
static
final
String
BASE_ROLE
=
"role_user"
;
/**
* 超级管理员角色
*/
public
static
final
String
ROLE_ADMIN
=
"role_admin"
;
/**
* 租户管理员角色
*/
public
static
final
String
ROLE_TENANT_ADMIN
=
"role_tenant_admin"
;
...
...
@@ -37,11 +27,6 @@ public class SecurityConstant {
public
static
final
String
NORMAL
=
"0"
;
/**
* 异常状态
*/
public
static
final
String
ABNORMAL
=
"1"
;
/**
* 手机登录URL
*/
public
static
final
String
MOBILE_TOKEN_URL
=
"/mobile/token"
;
...
...
common/common-security/src/main/java/com/github/tangyi/common/security/core/CustomUserDetailsService.java
View file @
b822b4d2
...
...
@@ -16,35 +16,35 @@ public interface CustomUserDetailsService {
/**
* 根据用户名和租户标识查询
*
* @param username username
* @param tenantCode tenantCode
* @param username username
* @return UserDetails
* @author tangyi
* @date 2019/05/28 21:06
*/
UserDetails
loadUserByIdentifierAndTenantCode
(
String
username
,
String
tenantCod
e
)
throws
UsernameNotFoundException
;
UserDetails
loadUserByIdentifierAndTenantCode
(
String
tenantCode
,
String
usernam
e
)
throws
UsernameNotFoundException
;
/**
* 根据社交账号和租户标识查询
*
* @param social social
* @param tenantCode tenantCode
* @param social social
* @param mobileUser mobileUser
* @return UserDetails
* @author tangyi
* @date 2019/06/22 21:08
*/
UserDetails
loadUserBySocialAndTenantCode
(
String
social
,
String
tenantCode
,
MobileUser
mobileUser
)
throws
UsernameNotFoundException
;
UserDetails
loadUserBySocialAndTenantCode
(
String
tenantCode
,
String
social
,
MobileUser
mobileUser
)
throws
UsernameNotFoundException
;
/**
* 根据微信openId和租户标识查询
*
* @param code code
* @param tenantCode tenantCode
* @param code code
* @param wxUser wxUser
* @return UserDetails
* @author tangyi
* @date 2019/07/05 20:04:59
*/
UserDetails
loadUserByWxCodeAndTenantCode
(
String
code
,
String
tenantC
ode
,
WxUser
wxUser
)
throws
UsernameNotFoundException
;
UserDetails
loadUserByWxCodeAndTenantCode
(
String
tenantCode
,
String
c
ode
,
WxUser
wxUser
)
throws
UsernameNotFoundException
;
}
common/common-security/src/main/java/com/github/tangyi/common/security/enums/Roles.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
common
.
security
.
enums
;
import
org.springframework.security.core.GrantedAuthority
;
/**
* 角色枚举
*
* @author tangyi
* @date 2019/11/02 12:30
*/
public
enum
Roles
implements
GrantedAuthority
{
/**
* 普通用户
*/
ROLE_USER
,
/**
* 超级管理员
*/
ROLE_ADMIN
,
/**
* 租户管理员
*/
ROLE_TENANT_ADMIN
,
/**
* 老师
*/
ROLE_TEACHER
;
@Override
public
String
getAuthority
()
{
return
name
();
}
}
common/common-security/src/main/java/com/github/tangyi/common/security/event/CustomAuthenticationFailureEvent.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
common
.
security
.
event
;
import
lombok.Data
;
import
org.springframework.context.ApplicationEvent
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.core.userdetails.UserDetails
;
/**
*
* 登录失败事件
*
* @author tangyi
* @date 2019-11-11 23:46
*/
@Data
public
class
CustomAuthenticationFailureEvent
extends
ApplicationEvent
{
private
UserDetails
userDetails
;
public
CustomAuthenticationFailureEvent
(
Authentication
authentication
,
UserDetails
userDetails
)
{
super
(
authentication
);
this
.
userDetails
=
userDetails
;
}
}
common/common-security/src/main/java/com/github/tangyi/common/security/event/CustomAuthenticationSuccessEvent.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
common
.
security
.
event
;
import
lombok.Data
;
import
org.springframework.context.ApplicationEvent
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.core.userdetails.UserDetails
;
/**
* 登录成功事件
*
* @author tangyi
* @date 2019-11-11 23:40
*/
@Data
public
class
CustomAuthenticationSuccessEvent
extends
ApplicationEvent
{
private
UserDetails
userDetails
;
public
CustomAuthenticationSuccessEvent
(
Authentication
authentication
,
UserDetails
userDetails
)
{
super
(
authentication
);
this
.
userDetails
=
userDetails
;
}
}
common/common-security/src/main/java/com/github/tangyi/common/security/exceptions/CustomOauthException.java
deleted
100644 → 0
View file @
8660b235
package
com
.
github
.
tangyi
.
common
.
security
.
exceptions
;
import
com.fasterxml.jackson.databind.annotation.JsonSerialize
;
import
com.github.tangyi.common.security.serializer.CustomOauthExceptionSerializer
;
import
lombok.Data
;
import
org.springframework.security.oauth2.common.exceptions.OAuth2Exception
;
/**
* 定制OAuth2Exception
*
* @author tangyi
* @date 2019/3/18 22:36
*/
@Data
@JsonSerialize
(
using
=
CustomOauthExceptionSerializer
.
class
)
public
class
CustomOauthException
extends
OAuth2Exception
{
/**
* 错误码
*/
private
int
code
;
public
CustomOauthException
(
String
msg
,
int
code
)
{
super
(
msg
);
this
.
code
=
code
;
}
}
common/common-security/src/main/java/com/github/tangyi/common/security/mobile/MobileAuthenticationProvider.java
View file @
b822b4d2
package
com
.
github
.
tangyi
.
common
.
security
.
mobile
;
import
com.github.tangyi.common.security.core.CustomUserDetailsService
;
import
com.github.tangyi.common.security.event.CustomAuthenticationFailureEvent
;
import
com.github.tangyi.common.security.event.CustomAuthenticationSuccessEvent
;
import
com.github.tangyi.common.security.tenant.TenantContextHolder
;
import
lombok.Data
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.context.ApplicationEventPublisher
;
import
org.springframework.context.support.MessageSourceAccessor
;
import
org.springframework.security.authentication.AuthenticationProvider
;
import
org.springframework.security.authentication.BadCredentialsException
;
...
...
@@ -24,17 +27,21 @@ public class MobileAuthenticationProvider implements AuthenticationProvider {
private
CustomUserDetailsService
customUserDetailsService
;
private
ApplicationEventPublisher
publisher
;
@Override
public
Authentication
authenticate
(
Authentication
authentication
)
throws
AuthenticationException
{
MobileAuthenticationToken
mobileAuthenticationToken
=
(
MobileAuthenticationToken
)
authentication
;
String
principal
=
mobileAuthenticationToken
.
getPrincipal
().
toString
();
UserDetails
userDetails
=
customUserDetailsService
.
loadUserBySocialAndTenantCode
(
principal
,
TenantContextHolder
.
getTenantCode
()
,
mobileAuthenticationToken
.
getMobileUser
());
UserDetails
userDetails
=
customUserDetailsService
.
loadUserBySocialAndTenantCode
(
TenantContextHolder
.
getTenantCode
(),
principal
,
mobileAuthenticationToken
.
getMobileUser
());
if
(
userDetails
==
null
)
{
log
.
debug
(
"Authentication failed: no credentials provided"
);
publisher
.
publishEvent
(
new
CustomAuthenticationFailureEvent
(
authentication
,
userDetails
));
throw
new
BadCredentialsException
(
messages
.
getMessage
(
"AbstractUserDetailsAuthenticationProvider.noopBindAccount"
,
"Noop Bind Account"
));
}
MobileAuthenticationToken
authenticationToken
=
new
MobileAuthenticationToken
(
userDetails
,
userDetails
.
getAuthorities
());
authenticationToken
.
setDetails
(
mobileAuthenticationToken
.
getDetails
());
publisher
.
publishEvent
(
new
CustomAuthenticationSuccessEvent
(
authentication
,
userDetails
));
return
authenticationToken
;
}
...
...
common/common-security/src/main/java/com/github/tangyi/common/security/mobile/MobileSecurityConfigurer.java
View file @
b822b4d2
...
...
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import
com.github.tangyi.common.security.core.CustomUserDetailsService
;
import
lombok.Data
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.ApplicationEventPublisher
;
import
org.springframework.security.authentication.AuthenticationEventPublisher
;
import
org.springframework.security.authentication.AuthenticationManager
;
import
org.springframework.security.config.annotation.SecurityConfigurerAdapter
;
...
...
@@ -27,6 +28,9 @@ public class MobileSecurityConfigurer extends SecurityConfigurerAdapter<DefaultS
@Autowired
private
AuthenticationEventPublisher
defaultAuthenticationEventPublisher
;
@Autowired
private
ApplicationEventPublisher
applicationEventPublisher
;
private
AuthenticationSuccessHandler
mobileLoginSuccessHandler
;
private
CustomUserDetailsService
userDetailsService
;
...
...
@@ -40,6 +44,7 @@ public class MobileSecurityConfigurer extends SecurityConfigurerAdapter<DefaultS
mobileAuthenticationFilter
.
setEventPublisher
(
defaultAuthenticationEventPublisher
);
MobileAuthenticationProvider
mobileAuthenticationProvider
=
new
MobileAuthenticationProvider
();
mobileAuthenticationProvider
.
setCustomUserDetailsService
(
userDetailsService
);
mobileAuthenticationProvider
.
setPublisher
(
applicationEventPublisher
);
// 增加手机登录的过滤器
http
.
authenticationProvider
(
mobileAuthenticationProvider
).
addFilterAfter
(
mobileAuthenticationFilter
,
UsernamePasswordAuthenticationFilter
.
class
);
}
...
...
common/common-security/src/main/java/com/github/tangyi/common/security/serializer/CustomOauthExceptionSerializer.java
deleted
100644 → 0
View file @
8660b235
package
com
.
github
.
tangyi
.
common
.
security
.
serializer
;
import
com.fasterxml.jackson.core.JsonGenerator
;
import
com.fasterxml.jackson.databind.SerializerProvider
;
import
com.fasterxml.jackson.databind.ser.std.StdSerializer
;
import
com.github.tangyi.common.security.exceptions.CustomOauthException
;
import
java.io.IOException
;
import
java.util.Map
;
/**
* 定制OauthException序列化
*
* @author tangyi
* @date 2019/3/18 22:37
*/
public
class
CustomOauthExceptionSerializer
extends
StdSerializer
<
CustomOauthException
>
{
public
CustomOauthExceptionSerializer
()
{
super
(
CustomOauthException
.
class
);
}
@Override
public
void
serialize
(
CustomOauthException
value
,
JsonGenerator
gen
,
SerializerProvider
provider
)
throws
IOException
{
gen
.
writeStartObject
();
// 封装属性,和ResponseBean对应
gen
.
writeNumberField
(
"status"
,
value
.
getCode
());
// 返回给前端的code
gen
.
writeNumberField
(
"code"
,
value
.
getCode
());
// 提示信息
gen
.
writeStringField
(
"msg"
,
value
.
getMessage
());
if
(
value
.
getAdditionalInformation
()
!=
null
)
{
for
(
Map
.
Entry
<
String
,
String
>
entry
:
value
.
getAdditionalInformation
().
entrySet
())
{
String
key
=
entry
.
getKey
();
String
add
=
entry
.
getValue
();
gen
.
writeStringField
(
key
,
add
);
}
}
gen
.
writeEndObject
();
}
}
common/common-security/src/main/java/com/github/tangyi/common/security/wx/WxAuthenticationProvider.java
View file @
b822b4d2
package
com
.
github
.
tangyi
.
common
.
security
.
wx
;
import
com.github.tangyi.common.security.core.CustomUserDetailsService
;
import
com.github.tangyi.common.security.event.CustomAuthenticationFailureEvent
;
import
com.github.tangyi.common.security.event.CustomAuthenticationSuccessEvent
;
import
com.github.tangyi.common.security.tenant.TenantContextHolder
;
import
lombok.Data
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.context.ApplicationEventPublisher
;
import
org.springframework.context.support.MessageSourceAccessor
;
import
org.springframework.security.authentication.AuthenticationProvider
;
import
org.springframework.security.authentication.BadCredentialsException
;
...
...
@@ -24,6 +27,8 @@ public class WxAuthenticationProvider implements AuthenticationProvider {
private
CustomUserDetailsService
customUserDetailsService
;
private
ApplicationEventPublisher
publisher
;
@Override
public
Authentication
authenticate
(
Authentication
authentication
)
throws
AuthenticationException
{
WxAuthenticationToken
wxAuthenticationToken
=
(
WxAuthenticationToken
)
authentication
;
...
...
@@ -32,10 +37,12 @@ public class WxAuthenticationProvider implements AuthenticationProvider {
UserDetails
userDetails
=
customUserDetailsService
.
loadUserByWxCodeAndTenantCode
(
principal
,
TenantContextHolder
.
getTenantCode
(),
wxAuthenticationToken
.
getWxUser
());
if
(
userDetails
==
null
)
{
log
.
debug
(
"Authentication failed: no credentials provided"
);
publisher
.
publishEvent
(
new
CustomAuthenticationFailureEvent
(
authentication
,
userDetails
));
throw
new
BadCredentialsException
(
messages
.
getMessage
(
"AbstractUserDetailsAuthenticationProvider.noopBindAccount"
,
"Noop Bind Account"
));
}
WxAuthenticationToken
authenticationToken
=
new
WxAuthenticationToken
(
userDetails
,
userDetails
.
getAuthorities
());
authenticationToken
.
setDetails
(
wxAuthenticationToken
.
getDetails
());
publisher
.
publishEvent
(
new
CustomAuthenticationSuccessEvent
(
authentication
,
userDetails
));
return
authenticationToken
;
}
...
...
common/common-security/src/main/java/com/github/tangyi/common/security/wx/WxSecurityConfigurer.java
View file @
b822b4d2
...
...
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import
com.github.tangyi.common.security.core.CustomUserDetailsService
;
import
lombok.Data
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.ApplicationEventPublisher
;
import
org.springframework.security.authentication.AuthenticationEventPublisher
;
import
org.springframework.security.authentication.AuthenticationManager
;
import
org.springframework.security.config.annotation.SecurityConfigurerAdapter
;
...
...
@@ -27,6 +28,9 @@ public class WxSecurityConfigurer extends SecurityConfigurerAdapter<DefaultSecur
@Autowired
private
AuthenticationEventPublisher
defaultAuthenticationEventPublisher
;
@Autowired
private
ApplicationEventPublisher
applicationEventPublisher
;
private
AuthenticationSuccessHandler
wxLoginSuccessHandler
;
private
CustomUserDetailsService
userDetailsService
;
...
...
@@ -40,6 +44,7 @@ public class WxSecurityConfigurer extends SecurityConfigurerAdapter<DefaultSecur
wxAuthenticationFilter
.
setEventPublisher
(
defaultAuthenticationEventPublisher
);
WxAuthenticationProvider
wxAuthenticationProvider
=
new
WxAuthenticationProvider
();
wxAuthenticationProvider
.
setCustomUserDetailsService
(
userDetailsService
);
wxAuthenticationProvider
.
setPublisher
(
applicationEventPublisher
);
// 增加微信登录的过滤器
http
.
authenticationProvider
(
wxAuthenticationProvider
).
addFilterAfter
(
wxAuthenticationFilter
,
UsernamePasswordAuthenticationFilter
.
class
);
}
...
...
frontend/spring-microservice-exam-web/package-lock.json
0 → 100644
View file @
b822b4d2
This source diff could not be displayed because it is too large. You can
view the blob
instead.
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/config/AopConfig.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
auth
.
config
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.EnableAspectJAutoProxy
;
/**
*
* 配置aop
*
* @author tangyi
* @date 2019-11-12 20:13
*/
@Configuration
@EnableAspectJAutoProxy
public
class
AopConfig
{
}
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/config/CustomAuthorizationServerConfigurer.java
View file @
b822b4d2
package
com
.
github
.
tangyi
.
auth
.
config
;
import
com.github.tangyi.auth.filter.CustomTokenEndpointAuthenticationFilter
;
import
com.github.tangyi.auth.security.CustomTokenConverter
;
import
com.github.tangyi.common.security.core.ClientDetailsServiceImpl
;
import
com.github.tangyi.common.security.exceptions.CustomOauthException
;
import
com.github.tangyi.user.api.feign.UserServiceClient
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.cloud.bootstrap.encrypt.KeyProperties
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.data.redis.connection.RedisConnectionFactory
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.security.authentication.AuthenticationManager
;
import
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
;
import
org.springframework.security.oauth2.common.exceptions.OAuth2Exception
;
import
org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer
;
import
org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter
;
import
org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer
;
import
org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer
;
import
org.springframework.security.oauth2.provider.ClientDetailsService
;
import
org.springframework.security.oauth2.provider.OAuth2RequestFactory
;
import
org.springframework.security.oauth2.provider.token.TokenStore
;
import
org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter
;
import
org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory
;
...
...
@@ -37,11 +30,6 @@ import javax.sql.DataSource;
public
class
CustomAuthorizationServerConfigurer
extends
AuthorizationServerConfigurerAdapter
{
/**
* 认证管理器
*/
private
final
AuthenticationManager
authenticationManager
;
/**
* redis连接工厂
*/
private
final
RedisConnectionFactory
redisConnectionFactory
;
...
...
@@ -56,21 +44,13 @@ public class CustomAuthorizationServerConfigurer extends AuthorizationServerConf
*/
private
final
KeyProperties
keyProperties
;
private
final
UserServiceClient
userServiceClient
;
private
OAuth2RequestFactory
oAuth2RequestFactory
;
@Autowired
public
CustomAuthorizationServerConfigurer
(
AuthenticationManager
authenticationManager
,
RedisConnectionFactory
redisConnectionFactory
,
public
CustomAuthorizationServerConfigurer
(
RedisConnectionFactory
redisConnectionFactory
,
DataSource
dataSource
,
KeyProperties
keyProperties
,
UserServiceClient
userServiceClient
)
{
this
.
authenticationManager
=
authenticationManager
;
KeyProperties
keyProperties
)
{
this
.
redisConnectionFactory
=
redisConnectionFactory
;
this
.
dataSource
=
dataSource
;
this
.
keyProperties
=
keyProperties
;
this
.
userServiceClient
=
userServiceClient
;
}
/**
...
...
@@ -123,25 +103,11 @@ public class CustomAuthorizationServerConfigurer extends AuthorizationServerConf
*/
@Override
public
void
configure
(
AuthorizationServerEndpointsConfigurer
endpoints
)
{
oAuth2RequestFactory
=
endpoints
.
getOAuth2RequestFactory
();
endpoints
// 将token存储到redis
.
tokenStore
(
tokenStore
())
// token增强
.
tokenEnhancer
(
jwtTokenEnhancer
())
// 认证管理器
.
authenticationManager
(
authenticationManager
)
// 异常处理
.
exceptionTranslator
(
e
->
{
if
(
e
instanceof
OAuth2Exception
)
{
OAuth2Exception
oAuth2Exception
=
(
OAuth2Exception
)
e
;
return
ResponseEntity
.
status
(
oAuth2Exception
.
getHttpErrorCode
())
.
body
(
new
CustomOauthException
(
oAuth2Exception
.
getMessage
(),
oAuth2Exception
.
getHttpErrorCode
()));
}
else
{
throw
e
;
}
});
.
tokenEnhancer
(
jwtTokenEnhancer
());
}
/**
...
...
@@ -158,7 +124,6 @@ public class CustomAuthorizationServerConfigurer extends AuthorizationServerConf
// 开启/oauth/check_token验证端口认证权限访问
.
checkTokenAccess
(
"isAuthenticated()"
)
.
allowFormAuthenticationForClients
();
//.addTokenEndpointAuthenticationFilter(new CustomTokenEndpointAuthenticationFilter(authenticationManager, oAuth2RequestFactory, userServiceClient));
}
}
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/config/SecurityConfig.java
View file @
b822b4d2
package
com
.
github
.
tangyi
.
auth
.
config
;
import
com.github.tangyi.auth.error.CustomOAuth2AccessDeniedHandler
;
import
com.github.tangyi.auth.security.CustomUserDetailsAuthenticationProvider
;
import
com.github.tangyi.common.security.core.CustomUserDetailsService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.ApplicationEventPublisher
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.security.authentication.AuthenticationManager
;
...
...
@@ -12,7 +14,10 @@ import org.springframework.security.config.annotation.method.configuration.Enabl
import
org.springframework.security.config.annotation.web.builders.HttpSecurity
;
import
org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
;
import
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
;
import
org.springframework.security.core.userdetails.UserDetailsService
;
import
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
;
import
org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerEndpointsConfiguration
;
import
org.springframework.security.web.access.AccessDeniedHandler
;
/**
* Spring Security配置
...
...
@@ -28,6 +33,12 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private
CustomUserDetailsService
userDetailsService
;
@Autowired
private
AuthorizationServerEndpointsConfiguration
endpoints
;
@Autowired
private
ApplicationEventPublisher
applicationEventPublisher
;
@Override
protected
void
configure
(
HttpSecurity
http
)
throws
Exception
{
http
...
...
@@ -35,6 +46,16 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
.
csrf
().
disable
()
.
authorizeRequests
()
.
anyRequest
().
authenticated
();
if
(!
endpoints
.
getEndpointsConfigurer
().
isUserDetailsServiceOverride
())
{
UserDetailsService
userDetailsService
=
http
.
getSharedObject
(
UserDetailsService
.
class
);
endpoints
.
getEndpointsConfigurer
().
userDetailsService
(
userDetailsService
);
}
// 认证管理器
endpoints
.
getEndpointsConfigurer
().
authenticationManager
(
authenticationManager
());
// accessDeniedHandler
http
.
exceptionHandling
()
.
accessDeniedHandler
(
accessDeniedHandler
());
}
@Bean
...
...
@@ -54,7 +75,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
*/
@Bean
public
AuthenticationProvider
authProvider
()
{
return
new
CustomUserDetailsAuthenticationProvider
(
encoder
(),
userDetailsService
);
return
new
CustomUserDetailsAuthenticationProvider
(
encoder
(),
userDetailsService
,
applicationEventPublisher
);
}
@Override
...
...
@@ -62,5 +83,10 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
protected
AuthenticationManager
authenticationManager
()
throws
Exception
{
return
super
.
authenticationManager
();
}
@Bean
public
AccessDeniedHandler
accessDeniedHandler
()
{
return
new
CustomOAuth2AccessDeniedHandler
();
}
}
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/controller/OauthClientDetailsController.java
View file @
b822b4d2
...
...
@@ -9,7 +9,7 @@ import com.github.tangyi.common.core.utils.PageUtil;
import
com.github.tangyi.common.core.utils.SysUtil
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.log.annotation.Log
;
import
com.github.tangyi.common.security.
constant.SecurityConstant
;
import
com.github.tangyi.common.security.
annotations.AdminAuthorization
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiImplicitParam
;
import
io.swagger.annotations.ApiImplicitParams
;
...
...
@@ -17,7 +17,6 @@ import io.swagger.annotations.ApiOperation;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang.ArrayUtils
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
;
import
org.springframework.web.bind.annotation.*
;
...
...
@@ -113,7 +112,7 @@ public class OauthClientDetailsController extends BaseController {
* @date 2019/03/30 16:57
*/
@PostMapping
@
PreAuthorize
(
"hasAuthority('sys:client:add') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminAuthorization
@ApiOperation
(
value
=
"创建客户端"
,
notes
=
"创建客户端"
)
@ApiImplicitParam
(
name
=
"oauthClientDetails"
,
value
=
"客户端实体oauthClientDetails"
,
required
=
true
,
dataType
=
"OauthClientDetails"
)
@Log
(
"新增客户端"
)
...
...
@@ -133,7 +132,7 @@ public class OauthClientDetailsController extends BaseController {
* @date 2019/03/30 16:56
*/
@PutMapping
@
PreAuthorize
(
"hasAuthority('sys:client:edit') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminAuthorization
@ApiOperation
(
value
=
"更新客户端信息"
,
notes
=
"根据客户端id更新客户端的基本信息"
)
@ApiImplicitParam
(
name
=
"oauthClientDetails"
,
value
=
"客户端实体oauthClientDetails"
,
required
=
true
,
dataType
=
"OauthClientDetails"
)
@Log
(
"修改客户端"
)
...
...
@@ -155,7 +154,7 @@ public class OauthClientDetailsController extends BaseController {
* @date 2019/03/30 16:59
*/
@DeleteMapping
(
"/{id}"
)
@
PreAuthorize
(
"hasAuthority('sys:client:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminAuthorization
@ApiOperation
(
value
=
"删除客户端"
,
notes
=
"根据ID删除客户端"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"客户端ID"
,
required
=
true
,
paramType
=
"path"
)
@Log
(
"删除客户端"
)
...
...
@@ -176,7 +175,7 @@ public class OauthClientDetailsController extends BaseController {
* @date 2019/03/30 17:01
*/
@PostMapping
(
"deleteAll"
)
@
PreAuthorize
(
"hasAuthority('sys:client:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminAuthorization
@ApiOperation
(
value
=
"批量删除客户端"
,
notes
=
"根据客户端id批量删除客户端"
)
@ApiImplicitParam
(
name
=
"oauthClientDetails"
,
value
=
"客户端信息"
,
dataType
=
"OauthClientDetails"
)
@Log
(
"批量删除客户端"
)
...
...
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/error/CustomOAuth2AccessDeniedHandler.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
auth
.
error
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.security.access.AccessDeniedException
;
import
org.springframework.security.oauth2.provider.error.AbstractOAuth2SecurityExceptionHandler
;
import
org.springframework.security.oauth2.provider.error.DefaultWebResponseExceptionTranslator
;
import
org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator
;
import
org.springframework.security.web.access.AccessDeniedHandler
;
import
org.springframework.web.context.request.ServletWebRequest
;
import
javax.servlet.ServletException
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
/**
*
* accessDeniedHandler,return ResponseBean
*
* @author tangyi
* @date 2019-11-11 21:24
*/
@Slf4j
public
class
CustomOAuth2AccessDeniedHandler
extends
AbstractOAuth2SecurityExceptionHandler
implements
AccessDeniedHandler
{
private
WebResponseExceptionTranslator
<?>
exceptionTranslator
=
new
DefaultWebResponseExceptionTranslator
();
private
CustomOAuth2ExceptionRenderer
exceptionRenderer
=
new
CustomOAuth2ExceptionRenderer
();
public
void
handle
(
HttpServletRequest
request
,
HttpServletResponse
response
,
AccessDeniedException
authException
)
throws
IOException
{
try
{
ResponseEntity
<?>
result
=
exceptionTranslator
.
translate
(
authException
);
result
=
enhanceResponse
(
result
,
authException
);
exceptionRenderer
.
handleResponseBeanResponse
(
result
,
new
ServletWebRequest
(
request
,
response
));
response
.
flushBuffer
();
}
catch
(
ServletException
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
}
catch
(
IOException
|
RuntimeException
e
)
{
throw
e
;
}
catch
(
Exception
e
)
{
// Wrap other Exceptions. These are not expected to happen
throw
new
RuntimeException
(
e
);
}
}
}
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/error/CustomOAuth2ExceptionRenderer.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
auth
.
error
;
import
com.github.tangyi.common.core.model.ResponseBean
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.http.*
;
import
org.springframework.http.converter.HttpMessageConverter
;
import
org.springframework.http.server.ServerHttpResponse
;
import
org.springframework.http.server.ServletServerHttpRequest
;
import
org.springframework.http.server.ServletServerHttpResponse
;
import
org.springframework.security.oauth2.http.converter.jaxb.JaxbOAuth2ExceptionMessageConverter
;
import
org.springframework.web.HttpMediaTypeNotAcceptableException
;
import
org.springframework.web.client.RestTemplate
;
import
org.springframework.web.context.request.NativeWebRequest
;
import
org.springframework.web.context.request.ServletWebRequest
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
/**
*
* render异常
*
* @author tangyi
* @date 2019-11-11 21:29
*/
@Slf4j
public
class
CustomOAuth2ExceptionRenderer
{
private
List
<
HttpMessageConverter
<?>>
messageConverters
=
geDefaultMessageConverters
();
public
void
handleResponseBeanResponse
(
ResponseEntity
<?>
responseEntity
,
ServletWebRequest
webRequest
)
throws
Exception
{
if
(
responseEntity
==
null
)
{
return
;
}
HttpInputMessage
inputMessage
=
createHttpInputMessage
(
webRequest
);
HttpOutputMessage
outputMessage
=
createHttpOutputMessage
(
webRequest
);
if
(
outputMessage
instanceof
ServerHttpResponse
)
{
((
ServerHttpResponse
)
outputMessage
).
setStatusCode
(
responseEntity
.
getStatusCode
());
}
HttpHeaders
entityHeaders
=
responseEntity
.
getHeaders
();
if
(!
entityHeaders
.
isEmpty
())
{
outputMessage
.
getHeaders
().
putAll
(
entityHeaders
);
}
Object
body
=
responseEntity
.
getBody
();
if
(
body
!=
null
)
{
// 返回ResponseBean
ResponseBean
<?>
responseBean
=
new
ResponseBean
<>(
body
);
responseBean
.
setStatus
(
responseEntity
.
getStatusCode
().
value
());
writeWithMessageConverters
(
responseBean
,
inputMessage
,
outputMessage
);
}
else
{
// flush headers
outputMessage
.
getBody
();
}
}
@SuppressWarnings
({
"unchecked"
,
"rawtypes"
})
private
void
writeWithMessageConverters
(
Object
returnValue
,
HttpInputMessage
inputMessage
,
HttpOutputMessage
outputMessage
)
throws
IOException
,
HttpMediaTypeNotAcceptableException
{
List
<
MediaType
>
acceptedMediaTypes
=
inputMessage
.
getHeaders
().
getAccept
();
if
(
acceptedMediaTypes
.
isEmpty
())
{
acceptedMediaTypes
=
Collections
.
singletonList
(
MediaType
.
ALL
);
}
MediaType
.
sortByQualityValue
(
acceptedMediaTypes
);
Class
<?>
returnValueType
=
returnValue
.
getClass
();
List
<
MediaType
>
allSupportedMediaTypes
=
new
ArrayList
<>();
for
(
MediaType
acceptedMediaType
:
acceptedMediaTypes
)
{
for
(
HttpMessageConverter
messageConverter
:
messageConverters
)
{
if
(
messageConverter
.
canWrite
(
returnValueType
,
acceptedMediaType
))
{
messageConverter
.
write
(
returnValue
,
acceptedMediaType
,
outputMessage
);
if
(
log
.
isDebugEnabled
())
{
MediaType
contentType
=
outputMessage
.
getHeaders
().
getContentType
();
if
(
contentType
==
null
)
{
contentType
=
acceptedMediaType
;
}
log
.
debug
(
"Written ["
+
returnValue
+
"] as \""
+
contentType
+
"\" using ["
+
messageConverter
+
"]"
);
}
return
;
}
}
}
for
(
HttpMessageConverter
messageConverter
:
messageConverters
)
{
allSupportedMediaTypes
.
addAll
(
messageConverter
.
getSupportedMediaTypes
());
}
throw
new
HttpMediaTypeNotAcceptableException
(
allSupportedMediaTypes
);
}
private
List
<
HttpMessageConverter
<?>>
geDefaultMessageConverters
()
{
List
<
HttpMessageConverter
<?>>
result
=
new
ArrayList
<>(
new
RestTemplate
().
getMessageConverters
());
result
.
add
(
new
JaxbOAuth2ExceptionMessageConverter
());
return
result
;
}
private
HttpInputMessage
createHttpInputMessage
(
NativeWebRequest
webRequest
)
{
return
new
ServletServerHttpRequest
(
webRequest
.
getNativeRequest
(
HttpServletRequest
.
class
));
}
private
HttpOutputMessage
createHttpOutputMessage
(
NativeWebRequest
webRequest
)
{
return
new
ServletServerHttpResponse
((
HttpServletResponse
)
webRequest
.
getNativeResponse
());
}
}
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/filter/CustomTokenEndpointAuthenticationFilter.java
deleted
100644 → 0
View file @
8660b235
package
com
.
github
.
tangyi
.
auth
.
filter
;
import
com.github.tangyi.auth.model.CustomUserDetails
;
import
com.github.tangyi.common.core.constant.CommonConstant
;
import
com.github.tangyi.common.core.constant.ServiceConstant
;
import
com.github.tangyi.common.core.model.Log
;
import
com.github.tangyi.common.core.utils.SysUtil
;
import
com.github.tangyi.user.api.feign.UserServiceClient
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.http.HttpMethod
;
import
org.springframework.scheduling.annotation.Async
;
import
org.springframework.security.authentication.AuthenticationManager
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.oauth2.provider.OAuth2RequestFactory
;
import
org.springframework.security.oauth2.provider.endpoint.TokenEndpointAuthenticationFilter
;
import
javax.servlet.FilterChain
;
import
javax.servlet.ServletException
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.ServletResponse
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
/**
*
* 登录成功后的处理,如记录登录日志
*
* @author tangyi
* @date 2019-10-11 12:08
*/
@Slf4j
public
class
CustomTokenEndpointAuthenticationFilter
extends
TokenEndpointAuthenticationFilter
{
private
UserServiceClient
userServiceClient
;
public
CustomTokenEndpointAuthenticationFilter
(
AuthenticationManager
authenticationManager
,
OAuth2RequestFactory
oAuth2RequestFactory
,
UserServiceClient
userServiceClient
)
{
super
(
authenticationManager
,
oAuth2RequestFactory
);
this
.
userServiceClient
=
userServiceClient
;
}
@Override
protected
void
onSuccessfulAuthentication
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Authentication
authentication
)
throws
IOException
{
// 登录成功后的处理
log
.
info
(
"CustomTokenEndpointAuthenticationFilter onSuccessfulAuthentication"
);
CustomUserDetails
userDetails
=
(
CustomUserDetails
)
authentication
.
getPrincipal
();
String
tenantCode
=
userDetails
.
getTenantCode
();
String
username
=
userDetails
.
getUsername
();
log
.
info
(
"CustomTokenEndpointAuthenticationFilter 登录成功, tenantCode: {}, username: {}"
,
tenantCode
,
username
);
// 记录日志
Log
logInfo
=
new
Log
();
logInfo
.
setCommonValue
(
username
,
SysUtil
.
getSysCode
(),
tenantCode
);
logInfo
.
setTitle
(
"用户登录"
);
logInfo
.
setType
(
CommonConstant
.
STATUS_NORMAL
);
logInfo
.
setMethod
(
request
.
getMethod
());
logInfo
.
setTime
(
String
.
valueOf
(
System
.
currentTimeMillis
()
-
userDetails
.
getStart
()));
logInfo
.
setRequestUri
(
request
.
getRequestURI
());
// 获取ip、浏览器信息
logInfo
.
setIp
(
request
.
getRemoteAddr
());
logInfo
.
setUserAgent
(
request
.
getHeader
(
HttpHeaders
.
USER_AGENT
));
logInfo
.
setServiceId
(
ServiceConstant
.
AUTH_SERVICE
);
// 记录日志
saveLoginSuccessLog
(
logInfo
);
}
@Override
public
void
doFilter
(
ServletRequest
req
,
ServletResponse
res
,
FilterChain
chain
)
throws
IOException
,
ServletException
{
// 认证前的特殊处理
// if (!condition) {
// throw new AuthenticationServiceException("condition not satisfied");
// }
log
.
info
(
"CustomTokenEndpointAuthenticationFilter doFilter"
);
super
.
doFilter
(
req
,
res
,
chain
);
}
/**
* 异步记录登录日志
*
* @author tangyi
* @date 2019/05/30 23:30
*/
@Async
public
void
saveLoginSuccessLog
(
Log
logInfo
)
{
try
{
userServiceClient
.
saveLog
(
logInfo
);
}
catch
(
Exception
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
}
}
}
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/listener/LoginFailureListener.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
auth
.
listener
;
import
com.github.tangyi.common.security.event.CustomAuthenticationFailureEvent
;
import
com.github.tangyi.user.api.feign.UserServiceClient
;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.context.ApplicationListener
;
import
org.springframework.stereotype.Component
;
/**
*
* 处理登录失败事件
*
* @author tangyi
* @date 2019-11-11 23:52
*/
@Slf4j
@AllArgsConstructor
@Component
public
class
LoginFailureListener
implements
ApplicationListener
<
CustomAuthenticationFailureEvent
>
{
private
final
UserServiceClient
userServiceClient
;
@Override
public
void
onApplicationEvent
(
CustomAuthenticationFailureEvent
event
)
{
// 登录失败后的处理
}
}
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/listener/LoginSuccessListener.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
auth
.
listener
;
import
com.github.tangyi.auth.model.CustomUserDetails
;
import
com.github.tangyi.common.core.constant.CommonConstant
;
import
com.github.tangyi.common.core.constant.ServiceConstant
;
import
com.github.tangyi.common.core.model.Log
;
import
com.github.tangyi.common.core.utils.DateUtils
;
import
com.github.tangyi.common.core.utils.SysUtil
;
import
com.github.tangyi.common.security.event.CustomAuthenticationSuccessEvent
;
import
com.github.tangyi.user.api.dto.UserDto
;
import
com.github.tangyi.user.api.feign.UserServiceClient
;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.context.ApplicationListener
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.scheduling.annotation.Async
;
import
org.springframework.security.core.userdetails.UserDetails
;
import
org.springframework.stereotype.Component
;
import
org.springframework.web.context.request.RequestAttributes
;
import
org.springframework.web.context.request.RequestContextHolder
;
import
org.springframework.web.context.request.ServletRequestAttributes
;
import
javax.servlet.http.HttpServletRequest
;
import
java.time.LocalDateTime
;
/**
*
* 处理登录成功事件
*
* @author tangyi
* @date 2019-11-11 23:48
*/
@Slf4j
@AllArgsConstructor
@Component
public
class
LoginSuccessListener
implements
ApplicationListener
<
CustomAuthenticationSuccessEvent
>
{
private
final
UserServiceClient
userServiceClient
;
@Override
public
void
onApplicationEvent
(
CustomAuthenticationSuccessEvent
event
)
{
// 登录成功后的处理
UserDetails
userDetails
=
event
.
getUserDetails
();
if
(
userDetails
instanceof
CustomUserDetails
)
{
CustomUserDetails
customUserDetails
=
(
CustomUserDetails
)
userDetails
;
String
tenantCode
=
customUserDetails
.
getTenantCode
();
String
username
=
userDetails
.
getUsername
();
log
.
info
(
"{} login success, tenantCode: {}"
,
username
,
tenantCode
);
// 记录日志
Log
logInfo
=
new
Log
();
logInfo
.
setTitle
(
"用户登录"
);
logInfo
.
setCommonValue
(
username
,
SysUtil
.
getSysCode
(),
tenantCode
);
logInfo
.
setTime
(
String
.
valueOf
(
System
.
currentTimeMillis
()
-
customUserDetails
.
getStart
()));
logInfo
.
setType
(
CommonConstant
.
STATUS_NORMAL
);
HttpServletRequest
request
=
currentRequestAttributes
().
getRequest
();
logInfo
.
setMethod
(
request
.
getMethod
());
logInfo
.
setRequestUri
(
request
.
getRequestURI
());
// 获取ip、浏览器信息
logInfo
.
setIp
(
request
.
getRemoteAddr
());
logInfo
.
setUserAgent
(
request
.
getHeader
(
HttpHeaders
.
USER_AGENT
));
logInfo
.
setServiceId
(
ServiceConstant
.
AUTH_SERVICE
);
// 记录日志和登录时间
UserDto
userDto
=
new
UserDto
();
userDto
.
setIdentifier
(
username
);
userDto
.
setLoginTime
(
DateUtils
.
asDate
(
LocalDateTime
.
now
()));
saveLoginInfo
(
logInfo
,
userDto
);
}
}
/**
* 异步记录登录日志
*
* @param logInfo logInfo
* @param userDto userDto
* @author tangyi
* @date 2019/05/30 23:30
*/
@Async
public
void
saveLoginInfo
(
Log
logInfo
,
UserDto
userDto
)
{
try
{
userServiceClient
.
saveLog
(
logInfo
);
//userServiceClient.updateUser(userDto);
}
catch
(
Exception
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
}
}
/**
*
* 获取当前request
*
* @return ServletRequestAttributes
* @author tangyi
* @date 2019-11-12 00:15
*/
private
static
ServletRequestAttributes
currentRequestAttributes
()
{
RequestAttributes
requestAttr
=
RequestContextHolder
.
currentRequestAttributes
();
if
(!(
requestAttr
instanceof
ServletRequestAttributes
))
{
throw
new
IllegalStateException
(
"Current request is not a servlet request"
);
}
return
(
ServletRequestAttributes
)
requestAttr
;
}
}
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/security/CustomUserDetailsAuthenticationProvider.java
View file @
b822b4d2
package
com
.
github
.
tangyi
.
auth
.
security
;
import
com.github.tangyi.common.security.event.CustomAuthenticationFailureEvent
;
import
com.github.tangyi.common.security.event.CustomAuthenticationSuccessEvent
;
import
com.github.tangyi.common.core.exceptions.TenantNotFoundException
;
import
com.github.tangyi.common.security.core.CustomUserDetailsService
;
import
com.github.tangyi.common.security.tenant.TenantContextHolder
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.context.ApplicationEventPublisher
;
import
org.springframework.security.authentication.BadCredentialsException
;
import
org.springframework.security.authentication.InternalAuthenticationServiceException
;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken
;
...
...
@@ -30,9 +33,12 @@ public class CustomUserDetailsAuthenticationProvider extends AbstractUserDetails
private
String
userNotFoundEncodedPassword
;
public
CustomUserDetailsAuthenticationProvider
(
PasswordEncoder
passwordEncoder
,
CustomUserDetailsService
userDetailsService
)
{
private
ApplicationEventPublisher
publisher
;
public
CustomUserDetailsAuthenticationProvider
(
PasswordEncoder
passwordEncoder
,
CustomUserDetailsService
userDetailsService
,
ApplicationEventPublisher
publisher
)
{
this
.
passwordEncoder
=
passwordEncoder
;
this
.
userDetailsService
=
userDetailsService
;
this
.
publisher
=
publisher
;
}
@Override
...
...
@@ -46,8 +52,10 @@ public class CustomUserDetailsAuthenticationProvider extends AbstractUserDetails
// 匹配密码
if
(!
passwordEncoder
.
matches
(
presentedPassword
,
userDetails
.
getPassword
()))
{
log
.
debug
(
"认证失败: 密码错误."
);
publisher
.
publishEvent
(
new
CustomAuthenticationFailureEvent
(
authentication
,
userDetails
));
throw
new
BadCredentialsException
(
messages
.
getMessage
(
"AbstractUserDetailsAuthenticationProvider.badCredentials"
,
"密码错误."
));
}
publisher
.
publishEvent
(
new
CustomAuthenticationSuccessEvent
(
authentication
,
userDetails
));
}
@Override
...
...
@@ -70,9 +78,9 @@ public class CustomUserDetailsAuthenticationProvider extends AbstractUserDetails
UserDetails
loadedUser
;
try
{
// 加载用户信息
loadedUser
=
this
.
userDetailsService
.
loadUserByIdentifierAndTenantCode
(
authentication
.
getPrincipal
().
toString
(),
TenantContextHolder
.
getTenantCode
());
loadedUser
=
this
.
userDetailsService
.
loadUserByIdentifierAndTenantCode
(
TenantContextHolder
.
getTenantCode
(),
authentication
.
getPrincipal
().
toString
());
}
catch
(
TenantNotFoundException
tenantNotFound
)
{
throw
tenantNotFound
;
throw
new
InternalAuthenticationServiceException
(
tenantNotFound
.
getMessage
(),
tenantNotFound
)
;
}
catch
(
UsernameNotFoundException
notFound
)
{
if
(
authentication
.
getCredentials
()
!=
null
)
{
String
presentedPassword
=
authentication
.
getCredentials
().
toString
();
...
...
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/security/CustomUserDetailsServiceImpl.java
View file @
b822b4d2
This diff is collapsed.
Click to expand it.
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/security/ValidateTenantAspect.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
auth
.
security
;
import
com.github.tangyi.common.core.exceptions.ServiceException
;
import
com.github.tangyi.common.core.exceptions.TenantNotFoundException
;
import
com.github.tangyi.common.core.model.ResponseBean
;
import
com.github.tangyi.common.core.utils.ResponseUtil
;
import
com.github.tangyi.user.api.feign.UserServiceClient
;
import
com.github.tangyi.user.api.module.Tenant
;
import
lombok.AllArgsConstructor
;
import
org.apache.commons.lang.StringUtils
;
import
org.aspectj.lang.annotation.Aspect
;
import
org.aspectj.lang.annotation.Before
;
import
org.springframework.stereotype.Component
;
/**
*
* 校验租户
*
* @author tangyi
* @date 2019-11-12 20:14
*/
@AllArgsConstructor
@Aspect
@Component
public
class
ValidateTenantAspect
{
private
final
UserServiceClient
userServiceClient
;
@Before
(
"execution(* com.github.tangyi.auth.security.CustomUserDetailsServiceImpl.load*(..)) && args(tenantCode,..)"
)
public
void
validateTenantCode
(
String
tenantCode
)
throws
TenantNotFoundException
{
// 获取tenantCode
if
(
StringUtils
.
isBlank
(
tenantCode
))
throw
new
TenantNotFoundException
(
"租户code不能为空."
);
// 先获取租户信息
ResponseBean
<
Tenant
>
tenantResponseBean
=
userServiceClient
.
findTenantByTenantCode
(
tenantCode
);
if
(!
ResponseUtil
.
isSuccess
(
tenantResponseBean
))
throw
new
ServiceException
(
"查询租户信息失败: "
+
tenantResponseBean
.
getMsg
());
Tenant
tenant
=
tenantResponseBean
.
getData
();
if
(
tenant
==
null
)
throw
new
TenantNotFoundException
(
"租户不存在."
);
}
}
modules/exam-service-parent/exam-service/src/main/java/com/github/tangyi/exam/controller/CourseController.java
View file @
b822b4d2
...
...
@@ -7,7 +7,7 @@ import com.github.tangyi.common.core.utils.PageUtil;
import
com.github.tangyi.common.core.utils.SysUtil
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.log.annotation.Log
;
import
com.github.tangyi.common.security.
constant.SecurityConstant
;
import
com.github.tangyi.common.security.
annotations.AdminTenantTeacherAuthorization
;
import
com.github.tangyi.exam.api.module.Course
;
import
com.github.tangyi.exam.service.CourseService
;
import
io.swagger.annotations.Api
;
...
...
@@ -17,7 +17,6 @@ import io.swagger.annotations.ApiOperation;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang.ArrayUtils
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
javax.validation.Valid
;
...
...
@@ -93,7 +92,7 @@ public class CourseController extends BaseController {
* @date 2018/11/10 21:31
*/
@PostMapping
@
PreAuthorize
(
"hasAuthority('exam:course:add') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"创建课程"
,
notes
=
"创建课程"
)
@ApiImplicitParam
(
name
=
"course"
,
value
=
"课程实体course"
,
required
=
true
,
dataType
=
"Course"
)
@Log
(
"新增课程"
)
...
...
@@ -111,7 +110,7 @@ public class CourseController extends BaseController {
* @date 2018/11/10 21:31
*/
@PutMapping
@
PreAuthorize
(
"hasAuthority('exam:course:edit') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"更新课程信息"
,
notes
=
"根据课程id更新课程的基本信息"
)
@ApiImplicitParam
(
name
=
"course"
,
value
=
"课程实体course"
,
required
=
true
,
dataType
=
"Course"
)
@Log
(
"更新课程"
)
...
...
@@ -129,7 +128,7 @@ public class CourseController extends BaseController {
* @date 2018/11/10 21:32
*/
@DeleteMapping
(
"{id}"
)
@
PreAuthorize
(
"hasAuthority('exam:course:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"删除课程"
,
notes
=
"根据ID删除课程"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"课程ID"
,
required
=
true
,
paramType
=
"path"
)
@Log
(
"删除课程"
)
...
...
@@ -158,7 +157,7 @@ public class CourseController extends BaseController {
* @date 2018/12/4 11:26
*/
@PostMapping
(
"deleteAll"
)
@
PreAuthorize
(
"hasAuthority('exam:course:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"批量删除课程"
,
notes
=
"根据课程id批量删除课程"
)
@ApiImplicitParam
(
name
=
"ids"
,
value
=
"课程ID"
,
dataType
=
"Long"
)
@Log
(
"批量删除课程"
)
...
...
modules/exam-service-parent/exam-service/src/main/java/com/github/tangyi/exam/controller/ExamRecordController.java
View file @
b822b4d2
...
...
@@ -4,11 +4,9 @@ import com.github.pagehelper.PageInfo;
import
com.github.tangyi.common.core.constant.CommonConstant
;
import
com.github.tangyi.common.core.model.ResponseBean
;
import
com.github.tangyi.common.core.utils.*
;
import
com.github.tangyi.common.core.vo.DeptVo
;
import
com.github.tangyi.common.core.vo.UserVo
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.log.annotation.Log
;
import
com.github.tangyi.common.security.
constant.SecurityConstant
;
import
com.github.tangyi.common.security.
annotations.AdminTenantTeacherAuthorization
;
import
com.github.tangyi.exam.api.dto.ExaminationRecordDto
;
import
com.github.tangyi.exam.api.dto.StartExamDto
;
import
com.github.tangyi.exam.api.enums.SubmitStatusEnum
;
...
...
@@ -18,7 +16,6 @@ import com.github.tangyi.exam.service.AnswerService;
import
com.github.tangyi.exam.service.ExamRecordService
;
import
com.github.tangyi.exam.service.ExaminationService
;
import
com.github.tangyi.exam.utils.ExamRecordUtil
;
import
com.github.tangyi.user.api.feign.UserServiceClient
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiImplicitParam
;
import
io.swagger.annotations.ApiImplicitParams
;
...
...
@@ -29,7 +26,6 @@ import org.apache.commons.collections4.CollectionUtils;
import
org.apache.commons.lang.ArrayUtils
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
javax.servlet.http.HttpServletRequest
;
...
...
@@ -58,8 +54,6 @@ public class ExamRecordController extends BaseController {
private
final
ExaminationService
examinationService
;
private
final
UserServiceClient
userServiceClient
;
private
final
AnswerService
answerService
;
/**
...
...
@@ -113,9 +107,6 @@ public class ExamRecordController extends BaseController {
if
(
CollectionUtils
.
isNotEmpty
(
examRecordPageInfo
.
getList
()))
{
// 查询考试信息
List
<
Examination
>
examinations
=
examinationService
.
findListById
(
examRecordPageInfo
.
getList
().
stream
().
map
(
ExaminationRecord:
:
getExaminationId
).
distinct
().
toArray
(
Long
[]::
new
));
// 查询用户信息
ResponseBean
<
List
<
UserVo
>>
returnT
=
userServiceClient
.
findUserById
(
examRecordPageInfo
.
getList
().
stream
().
map
(
ExaminationRecord:
:
getUserId
).
distinct
().
toArray
(
Long
[]::
new
));
if
(
returnT
!=
null
&&
CollectionUtils
.
isNotEmpty
(
returnT
.
getData
()))
{
examRecordPageInfo
.
getList
().
forEach
(
tempExamRecord
->
{
// 找到考试记录所属的考试信息
Examination
examinationRecordExamination
=
examinations
.
stream
()
...
...
@@ -139,29 +130,7 @@ public class ExamRecordController extends BaseController {
examRecordDtoList
.
add
(
examRecordDto
);
}
});
// 查询部门信息
ResponseBean
<
List
<
DeptVo
>>
deptResponseBean
=
userServiceClient
.
findDeptById
(
returnT
.
getData
().
stream
().
map
(
UserVo:
:
getDeptId
).
distinct
().
toArray
(
Long
[]::
new
));
examRecordDtoList
.
forEach
(
tempExamRecordDto
->
{
// 查询、设置用户信息
UserVo
examRecordDtoUserVo
=
returnT
.
getData
().
stream
()
.
filter
(
tempUserVo
->
tempExamRecordDto
.
getUserId
().
equals
(
tempUserVo
.
getId
()))
.
findFirst
().
orElse
(
null
);
if
(
examRecordDtoUserVo
!=
null
)
{
// 设置用户名
tempExamRecordDto
.
setUserName
(
examRecordDtoUserVo
.
getName
());
// 查询、设置部门信息
if
(
deptResponseBean
!=
null
&&
CollectionUtils
.
isNotEmpty
(
deptResponseBean
.
getData
()))
{
DeptVo
examRecordDtoDeptVo
=
deptResponseBean
.
getData
().
stream
()
// 根据部门ID过滤
.
filter
(
tempDept
->
tempDept
.
getId
().
equals
(
examRecordDtoUserVo
.
getDeptId
()))
.
findFirst
().
orElse
(
null
);
// 设置部门名称
if
(
examRecordDtoDeptVo
!=
null
)
tempExamRecordDto
.
setDeptName
(
examRecordDtoDeptVo
.
getDeptName
());
}
}
});
}
examRecordService
.
fillExamUserInfo
(
examRecordDtoList
,
examRecordPageInfo
.
getList
().
stream
().
map
(
ExaminationRecord:
:
getUserId
).
distinct
().
toArray
(
Long
[]::
new
));
}
examRecordDtoPageInfo
.
setTotal
(
examRecordPageInfo
.
getTotal
());
examRecordDtoPageInfo
.
setPages
(
examRecordPageInfo
.
getPages
());
...
...
@@ -184,10 +153,6 @@ public class ExamRecordController extends BaseController {
@ApiImplicitParam
(
name
=
"examRecord"
,
value
=
"考试记录实体examRecord"
,
required
=
true
,
dataType
=
"ExamRecord"
)
@Log
(
"新增考试记录"
)
public
ResponseBean
<
ExaminationRecord
>
addExamRecord
(
@RequestBody
@Valid
ExaminationRecord
examRecord
)
{
Examination
examination
=
new
Examination
();
examination
.
setId
(
examRecord
.
getExaminationId
());
// 查找考试信息
examination
=
examinationService
.
get
(
examination
);
examRecord
.
setCommonValue
(
SysUtil
.
getUser
(),
SysUtil
.
getSysCode
(),
SysUtil
.
getTenantCode
());
examRecord
.
setStartTime
(
examRecord
.
getCreateDate
());
examRecordService
.
insert
(
examRecord
);
...
...
@@ -245,7 +210,7 @@ public class ExamRecordController extends BaseController {
* @date 2018/12/31 22:28
*/
@PostMapping
(
"export"
)
@
PreAuthorize
(
"hasAuthority('exam:examRecord:export') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"导出考试成绩"
,
notes
=
"根据成绩id导出成绩"
)
@ApiImplicitParam
(
name
=
"ids"
,
value
=
"成绩ID"
,
required
=
true
,
dataType
=
"Long"
)
@Log
(
"导出考试记录"
)
...
...
@@ -292,30 +257,7 @@ public class ExamRecordController extends BaseController {
examRecordDtoList
.
add
(
recordDto
);
}
});
// 查询用户信息
ResponseBean
<
List
<
UserVo
>>
returnT
=
userServiceClient
.
findUserById
(
userIdSet
.
toArray
(
new
Long
[
0
]));
if
(
returnT
!=
null
&&
CollectionUtils
.
isNotEmpty
(
returnT
.
getData
()))
{
// 获取部门信息
ResponseBean
<
List
<
DeptVo
>>
deptResponseBean
=
userServiceClient
.
findDeptById
(
returnT
.
getData
().
stream
().
map
(
UserVo:
:
getDeptId
).
distinct
().
toArray
(
Long
[]::
new
));
examRecordDtoList
.
forEach
(
tempExamRecordDto
->
{
// 查询用户信息
UserVo
examRecordDtoUserVo
=
returnT
.
getData
().
stream
().
filter
(
tempUserVo
->
tempExamRecordDto
.
getUserId
().
equals
(
tempUserVo
.
getId
()))
.
findFirst
().
orElse
(
null
);
if
(
examRecordDtoUserVo
!=
null
)
{
tempExamRecordDto
.
setUserName
(
examRecordDtoUserVo
.
getName
());
// 查询部门信息
if
(
deptResponseBean
!=
null
&&
CollectionUtils
.
isNotEmpty
(
deptResponseBean
.
getData
()))
{
// 查找用户所属部门
DeptVo
examRecordDtoDeptVo
=
deptResponseBean
.
getData
().
stream
()
.
filter
(
tempDept
->
tempDept
.
getId
().
equals
(
examRecordDtoUserVo
.
getDeptId
()))
.
findFirst
().
orElse
(
null
);
// 设置所属部门名称
if
(
examRecordDtoDeptVo
!=
null
)
tempExamRecordDto
.
setDeptName
(
examRecordDtoDeptVo
.
getDeptName
());
}
}
});
}
examRecordService
.
fillExamUserInfo
(
examRecordDtoList
,
userIdSet
.
toArray
(
new
Long
[
0
]));
// 导出
ExcelToolUtil
.
exportExcel
(
request
.
getInputStream
(),
response
.
getOutputStream
(),
MapUtil
.
java2Map
(
examRecordDtoList
),
ExamRecordUtil
.
getExamRecordDtoMap
());
}
...
...
modules/exam-service-parent/exam-service/src/main/java/com/github/tangyi/exam/controller/ExaminationController.java
View file @
b822b4d2
...
...
@@ -7,8 +7,7 @@ import com.github.tangyi.common.core.utils.PageUtil;
import
com.github.tangyi.common.core.utils.SysUtil
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.log.annotation.Log
;
import
com.github.tangyi.common.security.constant.SecurityConstant
;
import
com.github.tangyi.exam.api.dto.AnswerCartDto
;
import
com.github.tangyi.common.security.annotations.AdminTenantTeacherAuthorization
;
import
com.github.tangyi.exam.api.dto.ExaminationDto
;
import
com.github.tangyi.exam.api.dto.SubjectDto
;
import
com.github.tangyi.exam.api.module.Course
;
...
...
@@ -25,7 +24,6 @@ import lombok.extern.slf4j.Slf4j;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.apache.commons.lang.ArrayUtils
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
javax.validation.Valid
;
...
...
@@ -152,7 +150,7 @@ public class ExaminationController extends BaseController {
* @date 2018/11/10 21:14
*/
@PostMapping
@
PreAuthorize
(
"hasAuthority('exam:exam:add') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"创建考试"
,
notes
=
"创建考试"
)
@ApiImplicitParam
(
name
=
"examinationDto"
,
value
=
"考试实体examinationDto"
,
required
=
true
,
dataType
=
"ExaminationDto"
)
@Log
(
"新增考试"
)
...
...
@@ -173,7 +171,7 @@ public class ExaminationController extends BaseController {
* @date 2018/11/10 21:15
*/
@PutMapping
@
PreAuthorize
(
"hasAuthority('exam:exam:edit') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"更新考试信息"
,
notes
=
"根据考试id更新考试的基本信息"
)
@ApiImplicitParam
(
name
=
"examinationDto"
,
value
=
"考试实体answer"
,
required
=
true
,
dataType
=
"ExaminationDto"
)
@Log
(
"更新考试"
)
...
...
@@ -195,7 +193,7 @@ public class ExaminationController extends BaseController {
* @date 2018/11/10 21:20
*/
@DeleteMapping
(
"{id}"
)
@
PreAuthorize
(
"hasAuthority('exam:exam:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"删除考试"
,
notes
=
"根据ID删除考试"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"考试ID"
,
required
=
true
,
paramType
=
"path"
)
@Log
(
"删除考试"
)
...
...
@@ -224,7 +222,7 @@ public class ExaminationController extends BaseController {
* @date 2018/12/03 22:03
*/
@PostMapping
(
"deleteAll"
)
@
PreAuthorize
(
"hasAuthority('exam:exam:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"批量删除考试"
,
notes
=
"根据考试id批量删除考试"
)
@ApiImplicitParam
(
name
=
"ids"
,
value
=
"考试ID"
,
dataType
=
"Long"
)
@Log
(
"批量删除考试"
)
...
...
modules/exam-service-parent/exam-service/src/main/java/com/github/tangyi/exam/controller/SubjectCategoryController.java
View file @
b822b4d2
...
...
@@ -7,7 +7,7 @@ import com.github.tangyi.common.core.utils.SysUtil;
import
com.github.tangyi.common.core.utils.TreeUtil
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.log.annotation.Log
;
import
com.github.tangyi.common.security.
constant.SecurityConstant
;
import
com.github.tangyi.common.security.
annotations.AdminTenantTeacherAuthorization
;
import
com.github.tangyi.exam.api.constants.ExamSubjectConstant
;
import
com.github.tangyi.exam.api.dto.SubjectCategoryDto
;
import
com.github.tangyi.exam.api.module.SubjectCategory
;
...
...
@@ -17,7 +17,6 @@ import io.swagger.annotations.ApiImplicitParam;
import
io.swagger.annotations.ApiOperation
;
import
lombok.AllArgsConstructor
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
javax.validation.Valid
;
...
...
@@ -89,7 +88,7 @@ public class SubjectCategoryController extends BaseController {
* @date 2018/12/04 22:00
*/
@PostMapping
@
PreAuthorize
(
"hasAuthority('exam:subject:category:add') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"创建分类"
,
notes
=
"创建分类"
)
@ApiImplicitParam
(
name
=
"subjectCategory"
,
value
=
"分类实体subjectCategory"
,
required
=
true
,
dataType
=
"SubjectCategory"
)
@Log
(
"新增题目分类"
)
...
...
@@ -108,7 +107,7 @@ public class SubjectCategoryController extends BaseController {
* @date 2018/12/04 22:01
*/
@PutMapping
@
PreAuthorize
(
"hasAuthority('exam:subject:category:edit') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"更新分类信息"
,
notes
=
"根据分类id更新分类的基本信息"
)
@ApiImplicitParam
(
name
=
"subjectCategory"
,
value
=
"分类实体subjectCategory"
,
required
=
true
,
dataType
=
"SubjectCategory"
)
@Log
(
"更新题目分类"
)
...
...
@@ -126,7 +125,7 @@ public class SubjectCategoryController extends BaseController {
* @date 2018/12/04 22:02
*/
@DeleteMapping
(
"/{id}"
)
@
PreAuthorize
(
"hasAuthority('exam:subject:category:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"删除分类"
,
notes
=
"根据ID删除分类"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"分类ID"
,
required
=
true
,
paramType
=
"path"
)
@Log
(
"删除题目分类"
)
...
...
modules/exam-service-parent/exam-service/src/main/java/com/github/tangyi/exam/controller/SubjectController.java
View file @
b822b4d2
...
...
@@ -7,7 +7,7 @@ import com.github.tangyi.common.core.model.ResponseBean;
import
com.github.tangyi.common.core.utils.*
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.log.annotation.Log
;
import
com.github.tangyi.common.security.
constant.SecurityConstant
;
import
com.github.tangyi.common.security.
annotations.AdminTenantTeacherAuthorization
;
import
com.github.tangyi.exam.api.dto.SubjectDto
;
import
com.github.tangyi.exam.service.AnswerService
;
import
com.github.tangyi.exam.service.SubjectService
;
...
...
@@ -17,7 +17,6 @@ import io.swagger.annotations.*;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.multipart.MultipartFile
;
...
...
@@ -101,7 +100,7 @@ public class SubjectController extends BaseController {
* @date 2018/11/10 21:43
*/
@PostMapping
@
PreAuthorize
(
"hasAuthority('exam:exam:subject:add') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"创建题目"
,
notes
=
"创建题目"
)
@ApiImplicitParam
(
name
=
"subject"
,
value
=
"题目信息"
,
required
=
true
,
dataType
=
"SubjectDto"
)
@Log
(
"新增题目"
)
...
...
@@ -119,7 +118,7 @@ public class SubjectController extends BaseController {
* @date 2018/11/10 21:43
*/
@PutMapping
@
PreAuthorize
(
"hasAuthority('exam:exam:subject:edit') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"更新题目信息"
,
notes
=
"根据题目id更新题目的基本信息"
)
@ApiImplicitParam
(
name
=
"subject"
,
value
=
"角色实体subject"
,
required
=
true
,
dataType
=
"Subject"
)
@Log
(
"更新题目"
)
...
...
@@ -137,7 +136,7 @@ public class SubjectController extends BaseController {
* @date 2018/11/10 21:43
*/
@DeleteMapping
(
"{id}"
)
@
PreAuthorize
(
"hasAuthority('exam:exam:subject:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"删除题目"
,
notes
=
"根据ID删除题目"
)
@ApiImplicitParams
({
@ApiImplicitParam
(
name
=
"id"
,
value
=
"题目ID"
,
required
=
true
,
dataType
=
"Long"
,
paramType
=
"path"
),
...
...
@@ -161,7 +160,7 @@ public class SubjectController extends BaseController {
* @date 2018/11/28 12:53
*/
@PostMapping
(
"export"
)
@
PreAuthorize
(
"hasAuthority('exam:exam:subject:export') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"导出题目"
,
notes
=
"根据分类id导出题目"
)
@ApiImplicitParams
({
@ApiImplicitParam
(
name
=
"ids"
,
value
=
"题目ID"
,
required
=
true
,
dataType
=
"Long"
),
...
...
@@ -200,7 +199,7 @@ public class SubjectController extends BaseController {
* @date 2018/11/28 12:59
*/
@RequestMapping
(
"import"
)
@
PreAuthorize
(
"hasAuthority('exam:exam:subject:import') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"导入题目"
,
notes
=
"导入题目"
)
@ApiImplicitParams
({
@ApiImplicitParam
(
name
=
"examinationId"
,
value
=
"考试ID"
,
dataType
=
"Long"
),
...
...
@@ -232,7 +231,7 @@ public class SubjectController extends BaseController {
* @date 2018/12/04 9:55
*/
@PostMapping
(
"deleteAll"
)
@
PreAuthorize
(
"hasAuthority('exam:exam:subject:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"批量删除题目"
,
notes
=
"根据题目id批量删除题目"
)
@ApiImplicitParam
(
name
=
"ids"
,
value
=
"题目ID"
,
dataType
=
"Long"
)
@Log
(
"批量删除题目"
)
...
...
modules/exam-service-parent/exam-service/src/main/java/com/github/tangyi/exam/service/ExamRecordService.java
View file @
b822b4d2
package
com
.
github
.
tangyi
.
exam
.
service
;
import
com.github.tangyi.common.core.constant.CommonConstant
;
import
com.github.tangyi.common.core.model.ResponseBean
;
import
com.github.tangyi.common.core.service.CrudService
;
import
com.github.tangyi.common.core.utils.ResponseUtil
;
import
com.github.tangyi.common.core.vo.DeptVo
;
import
com.github.tangyi.common.core.vo.UserVo
;
import
com.github.tangyi.exam.api.dto.ExaminationRecordDto
;
import
com.github.tangyi.exam.api.module.ExaminationRecord
;
import
com.github.tangyi.exam.mapper.ExamRecordMapper
;
import
com.github.tangyi.user.api.feign.UserServiceClient
;
import
lombok.AllArgsConstructor
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.springframework.cache.annotation.CacheEvict
;
import
org.springframework.cache.annotation.Cacheable
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.util.List
;
/**
* 考试记录service
*
...
...
@@ -20,6 +29,8 @@ import org.springframework.transaction.annotation.Transactional;
@Service
public
class
ExamRecordService
extends
CrudService
<
ExamRecordMapper
,
ExaminationRecord
>
{
private
final
UserServiceClient
userServiceClient
;
/**
* 查询考试记录
*
...
...
@@ -90,4 +101,40 @@ public class ExamRecordService extends CrudService<ExamRecordMapper, Examination
public
int
deleteAll
(
Long
[]
ids
)
{
return
super
.
deleteAll
(
ids
);
}
/**
* 获取用户、部门相关信息
* @param examRecordDtoList examRecordDtoList
* @param userIds userIds
*/
public
void
fillExamUserInfo
(
List
<
ExaminationRecordDto
>
examRecordDtoList
,
Long
[]
userIds
)
{
// 查询用户信息
ResponseBean
<
List
<
UserVo
>>
returnT
=
userServiceClient
.
findUserById
(
userIds
);
if
(
ResponseUtil
.
isSuccess
(
returnT
))
{
// 查询部门信息
ResponseBean
<
List
<
DeptVo
>>
deptResponseBean
=
userServiceClient
.
findDeptById
(
returnT
.
getData
().
stream
().
map
(
UserVo:
:
getDeptId
).
distinct
().
toArray
(
Long
[]::
new
));
if
(
ResponseUtil
.
isSuccess
(
deptResponseBean
))
{
examRecordDtoList
.
forEach
(
tempExamRecordDto
->
{
// 查询、设置用户信息
UserVo
examRecordDtoUserVo
=
returnT
.
getData
().
stream
()
.
filter
(
tempUserVo
->
tempExamRecordDto
.
getUserId
().
equals
(
tempUserVo
.
getId
()))
.
findFirst
().
orElse
(
null
);
if
(
examRecordDtoUserVo
!=
null
)
{
// 设置用户名
tempExamRecordDto
.
setUserName
(
examRecordDtoUserVo
.
getName
());
// 查询、设置部门信息
if
(
CollectionUtils
.
isNotEmpty
(
deptResponseBean
.
getData
()))
{
DeptVo
examRecordDtoDeptVo
=
deptResponseBean
.
getData
().
stream
()
// 根据部门ID过滤
.
filter
(
tempDept
->
tempDept
.
getId
().
equals
(
examRecordDtoUserVo
.
getDeptId
()))
.
findFirst
().
orElse
(
null
);
// 设置部门名称
if
(
examRecordDtoDeptVo
!=
null
)
tempExamRecordDto
.
setDeptName
(
examRecordDtoDeptVo
.
getDeptName
());
}
}
});
}
}
}
}
modules/exam-service-parent/exam-service/src/main/java/com/github/tangyi/exam/service/ExaminationService.java
View file @
b822b4d2
...
...
@@ -5,7 +5,6 @@ import com.github.tangyi.common.core.constant.CommonConstant;
import
com.github.tangyi.common.core.service.CrudService
;
import
com.github.tangyi.common.core.utils.PageUtil
;
import
com.github.tangyi.common.core.utils.SysUtil
;
import
com.github.tangyi.exam.api.dto.AnswerCartDto
;
import
com.github.tangyi.exam.api.dto.SubjectDto
;
import
com.github.tangyi.exam.api.module.Examination
;
import
com.github.tangyi.exam.api.module.ExaminationSubject
;
...
...
modules/exam-service-parent/exam-service/src/main/java/com/github/tangyi/exam/service/SubjectService.java
View file @
b822b4d2
...
...
@@ -23,7 +23,6 @@ import java.util.HashMap;
import
java.util.List
;
import
java.util.Map
;
import
java.util.stream.Collectors
;
import
java.util.stream.Stream
;
/**
* 题目service
...
...
modules/user-service-parent/user-service-api/src/main/java/com/github/tangyi/user/api/constant/MenuConstant.java
View file @
b822b4d2
...
...
@@ -45,5 +45,28 @@ public class MenuConstant {
* 修改
*/
public
static
final
String
PERMISSION_SUFFIX_MODIFY
=
":edit"
;
public
static
final
String
MENU_SYS
=
"sys"
;
/**
* 终端管理
*/
public
static
final
String
MENU_CLIENT
=
"sys:client"
;
/**
* 路由管理
*/
public
static
final
String
MENU_ROUTE
=
"sys:route"
;
/**
* 租户中心
*/
public
static
final
String
MENU_TENANT
=
"tenant"
;
/**
* 系统监控
*/
public
static
final
String
MENU_MONITOR
=
"monitor"
;
}
modules/user-service-parent/user-service/src/main/java/com/github/tangyi/user/controller/DeptController.java
View file @
b822b4d2
...
...
@@ -8,7 +8,7 @@ import com.github.tangyi.common.core.utils.TreeUtil;
import
com.github.tangyi.common.core.vo.DeptVo
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.log.annotation.Log
;
import
com.github.tangyi.common.security.
constant.SecurityConstant
;
import
com.github.tangyi.common.security.
annotations.AdminTenantTeacherAuthorization
;
import
com.github.tangyi.user.api.dto.DeptDto
;
import
com.github.tangyi.user.api.module.Dept
;
import
com.github.tangyi.user.service.DeptService
;
...
...
@@ -17,7 +17,6 @@ import io.swagger.annotations.ApiImplicitParam;
import
io.swagger.annotations.ApiOperation
;
import
lombok.AllArgsConstructor
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
javax.validation.Valid
;
...
...
@@ -91,7 +90,7 @@ public class DeptController extends BaseController {
* @date 2018/8/28 10:15
*/
@PostMapping
@
PreAuthorize
(
"hasAuthority('sys:dept:add') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"创建部门"
,
notes
=
"创建部门"
)
@ApiImplicitParam
(
name
=
"dept"
,
value
=
"部门实体"
,
required
=
true
,
dataType
=
"Dept"
)
@Log
(
"新增部门"
)
...
...
@@ -109,7 +108,7 @@ public class DeptController extends BaseController {
* @date 2018/8/28 10:16
*/
@DeleteMapping
(
"/{id}"
)
@
PreAuthorize
(
"hasAuthority('sys:dept:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"删除部门"
,
notes
=
"根据ID删除部门"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"部门ID"
,
required
=
true
,
paramType
=
"path"
)
@Log
(
"删除部门"
)
...
...
@@ -129,7 +128,7 @@ public class DeptController extends BaseController {
* @date 2018/8/28 10:22
*/
@PutMapping
@
PreAuthorize
(
"hasAuthority('sys:dept:edit') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"更新部门信息"
,
notes
=
"根据部门id更新部门的基本信息"
)
@ApiImplicitParam
(
name
=
"dept"
,
value
=
"部门实体"
,
required
=
true
,
dataType
=
"Dept"
)
@Log
(
"更新部门"
)
...
...
modules/user-service-parent/user-service/src/main/java/com/github/tangyi/user/controller/LogController.java
View file @
b822b4d2
...
...
@@ -7,7 +7,7 @@ import com.github.tangyi.common.core.model.ResponseBean;
import
com.github.tangyi.common.core.utils.PageUtil
;
import
com.github.tangyi.common.core.utils.SysUtil
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.security.
constant.SecurityConstant
;
import
com.github.tangyi.common.security.
annotations.AdminAuthorization
;
import
com.github.tangyi.user.service.LogService
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiImplicitParam
;
...
...
@@ -16,7 +16,6 @@ import io.swagger.annotations.ApiOperation;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang.ArrayUtils
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
javax.validation.Valid
;
...
...
@@ -98,10 +97,6 @@ public class LogController extends BaseController {
@ApiOperation
(
value
=
"新增日志"
,
notes
=
"新增日志"
)
@ApiImplicitParam
(
name
=
"log"
,
value
=
"日志实体Log"
,
required
=
true
,
dataType
=
"Log"
)
public
ResponseBean
<
Boolean
>
addLog
(
@RequestBody
@Valid
Log
log
)
{
if
(
log
.
getId
()
!=
null
)
log
.
setCommonValue
(
SysUtil
.
getUser
(),
SysUtil
.
getSysCode
(),
SysUtil
.
getTenantCode
());
if
(
true
)
return
null
;
// 保存日志
return
new
ResponseBean
<>(
logService
.
insert
(
log
)
>
0
);
}
...
...
@@ -115,7 +110,7 @@ public class LogController extends BaseController {
* @date 2018/10/31 21:27
*/
@DeleteMapping
(
"/{id}"
)
@
PreAuthorize
(
"hasAuthority('monitor:log:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminAuthorization
@ApiOperation
(
value
=
"删除日志"
,
notes
=
"根据ID删除日志"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"日志ID"
,
required
=
true
,
paramType
=
"path"
)
public
ResponseBean
<
Boolean
>
delete
(
@PathVariable
Long
id
)
{
...
...
@@ -133,7 +128,7 @@ public class LogController extends BaseController {
* @date 2018/12/4 10:12
*/
@PostMapping
(
"deleteAll"
)
@
PreAuthorize
(
"hasAuthority('monitor:log:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminAuthorization
@ApiOperation
(
value
=
"批量删除日志"
,
notes
=
"根据日志ids批量删除日志"
)
@ApiImplicitParam
(
name
=
"ids"
,
value
=
"日志ID"
,
dataType
=
"Long"
)
public
ResponseBean
<
Boolean
>
deleteAllLog
(
@RequestBody
Long
[]
ids
)
{
...
...
modules/user-service-parent/user-service/src/main/java/com/github/tangyi/user/controller/MenuController.java
View file @
b822b4d2
...
...
@@ -7,7 +7,7 @@ import com.github.tangyi.common.core.model.ResponseBean;
import
com.github.tangyi.common.core.utils.*
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.log.annotation.Log
;
import
com.github.tangyi.common.security.
constant.SecurityConstant
;
import
com.github.tangyi.common.security.
annotations.AdminTenantTeacherAuthorization
;
import
com.github.tangyi.user.api.dto.MenuDto
;
import
com.github.tangyi.user.api.module.Menu
;
import
com.github.tangyi.user.service.MenuService
;
...
...
@@ -17,7 +17,6 @@ import io.swagger.annotations.*;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.ArrayUtils
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.multipart.MultipartFile
;
...
...
@@ -90,7 +89,7 @@ public class MenuController extends BaseController {
* @date 2018/8/27 16:12
*/
@PostMapping
@
PreAuthorize
(
"hasAuthority('sys:menu:add') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"创建菜单"
,
notes
=
"创建菜单"
)
@ApiImplicitParam
(
name
=
"menu"
,
value
=
"角色实体menu"
,
required
=
true
,
dataType
=
"Menu"
)
@Log
(
"新增菜单"
)
...
...
@@ -108,7 +107,7 @@ public class MenuController extends BaseController {
* @date 2018/10/24 16:34
*/
@PutMapping
@
PreAuthorize
(
"hasAuthority('sys:menu:edit') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"更新菜单信息"
,
notes
=
"根据菜单id更新菜单的基本信息"
)
@ApiImplicitParam
(
name
=
"menu"
,
value
=
"角色实体menu"
,
required
=
true
,
dataType
=
"Menu"
)
@Log
(
"更新菜单"
)
...
...
@@ -126,7 +125,7 @@ public class MenuController extends BaseController {
* @date 2018/8/27 16:19
*/
@DeleteMapping
(
"/{id}"
)
@
PreAuthorize
(
"hasAuthority('sys:menu:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"删除菜单"
,
notes
=
"根据ID删除菜单"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"菜单ID"
,
required
=
true
,
paramType
=
"path"
)
@Log
(
"删除菜单"
)
...
...
@@ -243,7 +242,7 @@ public class MenuController extends BaseController {
* @date 2018/11/28 12:46
*/
@PostMapping
(
"export"
)
@
PreAuthorize
(
"hasAuthority('sys:menu:export') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"导出菜单"
,
notes
=
"根据菜单id导出菜单"
)
@ApiImplicitParam
(
name
=
"ids"
,
value
=
"菜单ID"
,
required
=
true
,
dataType
=
"Long"
)
@Log
(
"导出菜单"
)
...
...
@@ -280,7 +279,7 @@ public class MenuController extends BaseController {
* @date 2018/11/28 12:51
*/
@PostMapping
(
"import"
)
@
PreAuthorize
(
"hasAuthority('sys:menu:import') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"导入菜单"
,
notes
=
"导入菜单"
)
@Log
(
"导入菜单"
)
public
ResponseBean
<
Boolean
>
importMenu
(
@ApiParam
(
value
=
"要上传的文件"
,
required
=
true
)
MultipartFile
file
)
{
...
...
modules/user-service-parent/user-service/src/main/java/com/github/tangyi/user/controller/RoleController.java
View file @
b822b4d2
...
...
@@ -7,7 +7,7 @@ import com.github.tangyi.common.core.utils.PageUtil;
import
com.github.tangyi.common.core.utils.SysUtil
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.log.annotation.Log
;
import
com.github.tangyi.common.security.
constant.SecurityConstant
;
import
com.github.tangyi.common.security.
annotations.AdminTenantTeacherAuthorization
;
import
com.github.tangyi.user.api.module.Role
;
import
com.github.tangyi.user.service.RoleMenuService
;
import
com.github.tangyi.user.service.RoleService
;
...
...
@@ -19,7 +19,6 @@ import lombok.AllArgsConstructor;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang.ArrayUtils
;
import
org.apache.commons.lang.StringUtils
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
javax.validation.Valid
;
...
...
@@ -120,7 +119,7 @@ public class RoleController extends BaseController {
* @date 2018/9/14 18:22
*/
@PutMapping
@
PreAuthorize
(
"hasAuthority('sys:role:edit') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"更新角色信息"
,
notes
=
"根据角色id更新角色的基本信息"
)
@ApiImplicitParam
(
name
=
"role"
,
value
=
"角色实体role"
,
required
=
true
,
dataType
=
"RoleVo"
)
@Log
(
"修改角色"
)
...
...
@@ -162,7 +161,7 @@ public class RoleController extends BaseController {
* @date 2018/9/14 18:23
*/
@PostMapping
@
PreAuthorize
(
"hasAuthority('sys:role:add') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"创建角色"
,
notes
=
"创建角色"
)
@ApiImplicitParam
(
name
=
"role"
,
value
=
"角色实体role"
,
required
=
true
,
dataType
=
"RoleVo"
)
@Log
(
"新增角色"
)
...
...
@@ -180,7 +179,7 @@ public class RoleController extends BaseController {
* @date 2018/9/14 18:24
*/
@DeleteMapping
(
"/{id}"
)
@
PreAuthorize
(
"hasAuthority('sys:role:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"删除角色"
,
notes
=
"根据ID删除角色"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"角色ID"
,
required
=
true
,
paramType
=
"path"
)
@Log
(
"删除角色"
)
...
...
@@ -201,7 +200,7 @@ public class RoleController extends BaseController {
* @date 2018/12/4 10:00
*/
@PostMapping
(
"deleteAll"
)
@
PreAuthorize
(
"hasAuthority('sys:role:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"批量删除角色"
,
notes
=
"根据角色id批量删除角色"
)
@ApiImplicitParam
(
name
=
"ids"
,
value
=
"角色ID"
,
dataType
=
"Long"
)
@Log
(
"批量删除角色"
)
...
...
modules/user-service-parent/user-service/src/main/java/com/github/tangyi/user/controller/UserController.java
View file @
b822b4d2
...
...
@@ -8,6 +8,7 @@ import com.github.tangyi.common.core.utils.*;
import
com.github.tangyi.common.core.vo.UserVo
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.log.annotation.Log
;
import
com.github.tangyi.common.security.annotations.AdminTenantTeacherAuthorization
;
import
com.github.tangyi.common.security.constant.SecurityConstant
;
import
com.github.tangyi.user.api.dto.UserDto
;
import
com.github.tangyi.user.api.dto.UserInfoDto
;
...
...
@@ -26,7 +27,6 @@ import org.apache.commons.lang.ArrayUtils;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.security.oauth2.provider.OAuth2Authentication
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.multipart.MultipartFile
;
...
...
@@ -175,7 +175,7 @@ public class UserController extends BaseController {
* @date 2018/8/26 14:34
*/
@PostMapping
@
PreAuthorize
(
"hasAuthority('sys:user:add') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"创建用户"
,
notes
=
"创建用户"
)
@ApiImplicitParam
(
name
=
"userDto"
,
value
=
"用户实体user"
,
required
=
true
,
dataType
=
"UserDto"
)
@Log
(
"新增用户"
)
...
...
@@ -193,7 +193,7 @@ public class UserController extends BaseController {
* @date 2018/8/26 15:06
*/
@PutMapping
(
"/{id:[a-zA-Z0-9,]+}"
)
@
PreAuthorize
(
"hasAuthority('sys:user:edit') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"更新用户信息"
,
notes
=
"根据用户id更新用户的基本信息、角色信息"
)
@ApiImplicitParam
(
name
=
"userDto"
,
value
=
"用户实体user"
,
required
=
true
,
dataType
=
"UserDto"
)
@Log
(
"修改用户"
)
...
...
@@ -266,7 +266,7 @@ public class UserController extends BaseController {
* @date 2018/8/26 15:28
*/
@DeleteMapping
(
"/{id}"
)
@
PreAuthorize
(
"hasAuthority('sys:user:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"删除用户"
,
notes
=
"根据ID删除用户"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"用户ID"
,
required
=
true
,
paramType
=
"path"
)
@Log
(
"删除用户"
)
...
...
@@ -291,7 +291,7 @@ public class UserController extends BaseController {
* @date 2018/11/26 22:11
*/
@PostMapping
(
"export"
)
@
PreAuthorize
(
"hasAuthority('sys:user:export') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"导出用户"
,
notes
=
"根据用户id导出用户"
)
@ApiImplicitParam
(
name
=
"userVo"
,
value
=
"用户信息"
,
required
=
true
,
dataType
=
"UserVo"
)
@Log
(
"导出用户"
)
...
...
@@ -339,7 +339,7 @@ public class UserController extends BaseController {
* @date 2018/11/28 12:44
*/
@PostMapping
(
"import"
)
@
PreAuthorize
(
"hasAuthority('sys:user:import') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"导入数据"
,
notes
=
"导入数据"
)
@Log
(
"导入用户"
)
public
ResponseBean
<
Boolean
>
importUser
(
@ApiParam
(
value
=
"要上传的文件"
,
required
=
true
)
MultipartFile
file
,
HttpServletRequest
request
)
{
...
...
@@ -365,7 +365,7 @@ public class UserController extends BaseController {
* @date 2018/12/4 9:58
*/
@PostMapping
(
"deleteAll"
)
@
PreAuthorize
(
"hasAuthority('sys:user:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"批量删除用户"
,
notes
=
"根据用户id批量删除用户"
)
@ApiImplicitParam
(
name
=
"ids"
,
value
=
"用户信息"
,
dataType
=
"Long"
)
@Log
(
"批量删除用户"
)
...
...
@@ -460,7 +460,7 @@ public class UserController extends BaseController {
* @date 2019/6/7 12:00
*/
@PutMapping
(
"/resetPassword"
)
@
PreAuthorize
(
"hasAuthority('sys:user:edit') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"重置密码"
,
notes
=
"根据用户id重置密码"
)
@ApiImplicitParam
(
name
=
"userDto"
,
value
=
"用户实体user"
,
required
=
true
,
dataType
=
"UserDto"
)
@Log
(
"重置密码"
)
...
...
modules/user-service-parent/user-service/src/main/java/com/github/tangyi/user/service/MenuService.java
View file @
b822b4d2
...
...
@@ -7,6 +7,7 @@ import com.github.tangyi.common.core.service.CrudService;
import
com.github.tangyi.common.core.utils.SysUtil
;
import
com.github.tangyi.common.core.utils.TreeUtil
;
import
com.github.tangyi.common.security.constant.SecurityConstant
;
import
com.github.tangyi.common.security.enums.Roles
;
import
com.github.tangyi.common.security.utils.SecurityUtil
;
import
com.github.tangyi.user.api.constant.MenuConstant
;
import
com.github.tangyi.user.api.dto.MenuDto
;
...
...
@@ -80,7 +81,7 @@ public class MenuService extends CrudService<MenuMapper, Menu> {
List
<
Role
>
roleList
=
SecurityUtil
.
getCurrentAuthentication
().
getAuthorities
().
stream
()
// 按角色过滤
.
filter
(
authority
->
authority
.
getAuthority
()
!=
null
&&
authority
.
getAuthority
()
.
startsWith
(
"role
_"
)).
map
(
authority
->
{
.
startsWith
(
"ROLE
_"
)).
map
(
authority
->
{
Role
role
=
new
Role
();
role
.
setRoleCode
(
authority
.
getAuthority
());
return
role
;
...
...
@@ -88,7 +89,7 @@ public class MenuService extends CrudService<MenuMapper, Menu> {
// 根据角色code批量查找菜单
List
<
Menu
>
tenantMenus
=
finMenuByRoleList
(
roleList
,
tenantCode
);
// 组装数据
userMenus
=
mergeMenu
(
defaultMenus
,
tenantMenus
);
userMenus
=
mergeMenu
(
getTenantMenus
(
defaultMenus
)
,
tenantMenus
);
}
if
(
CollectionUtils
.
isNotEmpty
(
userMenus
))
{
userMenus
.
stream
()
...
...
@@ -99,7 +100,8 @@ public class MenuService extends CrudService<MenuMapper, Menu> {
// 去重
.
distinct
().
forEach
(
menuDtoList:
:
add
);
// 排序、构建树形关系
return
TreeUtil
.
buildTree
(
CollUtil
.
sort
(
menuDtoList
,
Comparator
.
comparingInt
(
MenuDto:
:
getSort
)),
CommonConstant
.
ROOT
);
return
TreeUtil
.
buildTree
(
CollUtil
.
sort
(
menuDtoList
,
Comparator
.
comparingInt
(
MenuDto:
:
getSort
)),
CommonConstant
.
ROOT
);
}
return
Lists
.
newArrayList
();
}
...
...
@@ -298,7 +300,8 @@ public class MenuService extends CrudService<MenuMapper, Menu> {
// 租户菜单
tenantMenus
.
forEach
(
tenantMenu
->
{
Optional
<
Menu
>
exist
=
userMenus
.
stream
()
.
filter
(
userMenu
->
userMenu
.
getName
().
equals
(
tenantMenu
.
getName
())
&&
userMenu
.
getParentId
().
equals
(
tenantMenu
.
getParentId
())).
findFirst
();
.
filter
(
userMenu
->
userMenu
.
getName
().
equals
(
tenantMenu
.
getName
())
&&
userMenu
.
getParentId
()
.
equals
(
tenantMenu
.
getParentId
())).
findFirst
();
if
(!
exist
.
isPresent
())
{
userMenus
.
add
(
tenantMenu
);
}
...
...
@@ -349,6 +352,7 @@ public class MenuService extends CrudService<MenuMapper, Menu> {
/**
* 根据租户code删除
*
* @param menu menu
* @return int
*/
...
...
@@ -356,4 +360,25 @@ public class MenuService extends CrudService<MenuMapper, Menu> {
public
int
deleteByTenantCode
(
Menu
menu
)
{
return
this
.
dao
.
deleteByTenantCode
(
menu
);
}
/**
* 获取租户权限的菜单
* @param defaultMenus defaultMenus
* @return List
*/
private
List
<
Menu
>
getTenantMenus
(
List
<
Menu
>
defaultMenus
)
{
List
<
Menu
>
tenantMenus
=
new
ArrayList
<>();
if
(
CollectionUtils
.
isNotEmpty
(
defaultMenus
))
{
defaultMenus
.
forEach
(
menu
->
{
String
permission
=
menu
.
getPermission
();
// 过滤客户端管理、路由管理、系统监控菜单
if
(!
permission
.
equals
(
MenuConstant
.
MENU_CLIENT
)
&&
!
permission
.
equals
(
MenuConstant
.
MENU_ROUTE
)
&&
!
permission
.
equals
(
MenuConstant
.
MENU_TENANT
)
&&
!
permission
.
equals
(
MenuConstant
.
MENU_MONITOR
))
{
tenantMenus
.
add
(
menu
);
}
});
}
return
tenantMenus
;
}
}
pom.xml
View file @
b822b4d2
...
...
@@ -72,6 +72,7 @@
<okhttp.version>
3.8.1
</okhttp.version>
<aliyun.version>
4.0.3
</aliyun.version>
<weixin.version>
3.4.0
</weixin.version>
<jjwt.version>
0.9.0
</jjwt.version>
<!-- docker -->
<docker.maven.verion>
1.4.3
</docker.maven.verion>
...
...
@@ -301,6 +302,13 @@
<artifactId>
weixin-java-pay
</artifactId>
<version>
${weixin.version}
</version>
</dependency>
<!-- jjwt -->
<dependency>
<groupId>
io.jsonwebtoken
</groupId>
<artifactId>
jjwt
</artifactId>
<version>
${jjwt.version}
</version>
</dependency>
</dependencies>
</dependencyManagement>
...
...
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