Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
O
on-site-service
Project
Project
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
external
on-site-service
Commits
239f7354
Commit
239f7354
authored
Jul 04, 2022
by
shangtx
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: admin权限
parent
f94d388b
Show whitespace changes
Inline
Side-by-side
Showing
34 changed files
with
707 additions
and
162 deletions
+707
-162
LoginController.java
...m/onsiteservice/admin/controller/sys/LoginController.java
+43
-0
LoginInitVO.java
...om/onsiteservice/admin/controller/sys/vo/LoginInitVO.java
+33
-0
SecurityConfiguration.java
...m/onsiteservice/admin/security/SecurityConfiguration.java
+106
-0
SecurityService.java
...ava/com/onsiteservice/admin/security/SecurityService.java
+95
-0
CustomUserDetailsService.java
...min/security/authentication/CustomUserDetailsService.java
+47
-0
JwtAuthenticationFilter.java
...dmin/security/authentication/JwtAuthenticationFilter.java
+76
-0
JwtLoginFilter.java
...service/admin/security/authentication/JwtLoginFilter.java
+97
-0
CustomAccessDeniedHandler.java
...ice/admin/security/handler/CustomAccessDeniedHandler.java
+28
-0
CustomAuthenticationEntryPoint.java
...dmin/security/handler/CustomAuthenticationEntryPoint.java
+33
-0
AccountCredentials.java
...onsiteservice/admin/security/pojo/AccountCredentials.java
+18
-0
CustomUserDetails.java
.../onsiteservice/admin/security/pojo/CustomUserDetails.java
+57
-0
TokenTimeProperties.java
...nsiteservice/admin/security/pojo/TokenTimeProperties.java
+19
-0
TokenVO.java
...n/java/com/onsiteservice/admin/security/pojo/TokenVO.java
+35
-0
spring-security.png
...com/onsiteservice/admin/security/pojo/spring-security.png
+0
-0
application-dev.yaml
admin/src/main/resources/application-dev.yaml
+1
-1
application-prod.yaml
admin/src/main/resources/application-prod.yaml
+0
-13
application-sit.yaml
admin/src/main/resources/application-sit.yaml
+0
-5
application-test.yaml
admin/src/main/resources/application-test.yaml
+0
-9
application.yaml
admin/src/main/resources/application.yaml
+1
-2
JasyptTest.java
admin/src/test/java/com/onsiteservice/admin/JasyptTest.java
+8
-0
pom.xml
common/pom.xml
+2
-2
RateLimiterAspect.java
...iteservice/common/annotation/limit/RateLimiterAspect.java
+1
-1
UniqueCheckAspect.java
...rvice/common/annotation/validation/UniqueCheckAspect.java
+1
-1
ServiceLogAspect.java
...n/java/com/onsiteservice/common/log/ServiceLogAspect.java
+1
-1
application-common-dev.yaml
constant/src/main/resources/application-common-dev.yaml
+1
-1
application-common-prod.yaml
constant/src/main/resources/application-common-prod.yaml
+0
-62
application-common-sit.yaml
constant/src/main/resources/application-common-sit.yaml
+0
-20
application-common-test.yaml
constant/src/main/resources/application-common-test.yaml
+0
-21
application-common.yaml
constant/src/main/resources/application-common.yaml
+1
-1
application-third-service-prod.yaml
...nt/src/main/resources/application-third-service-prod.yaml
+0
-18
application-third-service-sit.yaml
...ant/src/main/resources/application-third-service-sit.yaml
+0
-1
application-third-service-test.yaml
...nt/src/main/resources/application-third-service-test.yaml
+0
-1
application-third-service.yaml
constant/src/main/resources/application-third-service.yaml
+3
-1
ShedLockConfig.java
...com/onsiteservice/dao/common/schedule/ShedLockConfig.java
+0
-1
No files found.
admin/src/main/java/com/onsiteservice/admin/controller/sys/LoginController.java
0 → 100644
View file @
239f7354
package
com
.
onsiteservice
.
admin
.
controller
.
sys
;
import
com.onsiteservice.admin.controller.sys.vo.LoginInitVO
;
import
com.onsiteservice.admin.security.pojo.AccountCredentials
;
import
com.onsiteservice.common.annotation.user.CurrentUserId
;
import
com.onsiteservice.core.result.Result
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.*
;
import
javax.annotation.Resource
;
import
static
com
.
onsiteservice
.
core
.
result
.
ResultGenerator
.
success
;
/**
* @author 潘维吉
* @date 2020/3/7 14:19
* @email 406798106@qq.com
* @description 业务控制类
*/
@Api
(
tags
=
"登录密码"
)
@RestController
@RequestMapping
@Validated
public
class
LoginController
{
// @Resource
// private BaseBusinessService baseBusinessService;
@ApiOperation
(
value
=
"登录"
,
notes
=
"作者: 潘维吉。 Spring Security处理, 不配置浏览器会出现CORS跨域问题"
)
@PostMapping
(
"login"
)
public
AccountCredentials
login
(
@RequestBody
AccountCredentials
account
)
{
return
account
;
}
@ApiOperation
(
value
=
"获取菜单、权限、用户"
,
notes
=
"作者: 潘维吉"
)
@GetMapping
(
"login/init"
)
public
Result
<
LoginInitVO
>
init
(
@CurrentUserId
Long
userId
)
{
return
success
(
/*baseBusinessService.init(userId)*/
);
}
}
admin/src/main/java/com/onsiteservice/admin/controller/sys/vo/LoginInitVO.java
0 → 100644
View file @
239f7354
package
com
.
onsiteservice
.
admin
.
controller
.
sys
.
vo
;
import
com.onsiteservice.entity.sys.vo.MenuTreeVO
;
import
lombok.Getter
;
import
lombok.Setter
;
import
lombok.ToString
;
import
java.util.List
;
/**
* @author 潘维吉
* @date 2020/3/7 14:41
* @email 406798106@qq.com
* @description 登录初始化数据
*/
@Getter
@Setter
@ToString
public
class
LoginInitVO
<
T
,
E
>
{
/**
* 当前登录用户
*/
private
T
userInfo
;
/**
* 菜单树
*/
private
List
<
MenuTreeVO
>
menuList
;
/**
* 业务操作集合
*/
private
List
<
E
>
operateList
;
}
admin/src/main/java/com/onsiteservice/admin/security/SecurityConfiguration.java
0 → 100644
View file @
239f7354
package
com
.
onsiteservice
.
admin
.
security
;
import
com.onsiteservice.admin.security.authentication.CustomUserDetailsService
;
import
com.onsiteservice.admin.security.authentication.JwtAuthenticationFilter
;
import
com.onsiteservice.admin.security.authentication.JwtLoginFilter
;
import
com.onsiteservice.admin.security.handler.CustomAccessDeniedHandler
;
import
com.onsiteservice.admin.security.handler.CustomAuthenticationEntryPoint
;
import
com.onsiteservice.constant.constant.Constants
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.core.annotation.Order
;
import
org.springframework.http.HttpMethod
;
import
org.springframework.security.authentication.AuthenticationManager
;
import
org.springframework.security.config.BeanIds
;
import
org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
;
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.config.http.SessionCreationPolicy
;
import
org.springframework.security.core.userdetails.UserDetailsService
;
import
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
;
import
org.springframework.security.crypto.password.PasswordEncoder
;
import
org.springframework.security.web.access.AccessDeniedHandler
;
import
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
;
import
javax.annotation.Resource
;
/**
* 安全权限配置
*/
@Order
(
2
)
// 核心core安全配置优先级
@ConditionalOnProperty
(
prefix
=
"project.admin-security"
,
name
=
{
"enabled"
},
matchIfMissing
=
true
)
@Configuration
@EnableWebSecurity
(
debug
=
true
)
public
class
SecurityConfiguration
extends
WebSecurityConfigurerAdapter
{
@Value
(
"${project.jwt.ant-paths}"
)
private
String
antPaths
;
@Resource
private
CustomAuthenticationEntryPoint
customAuthenticationEntryPoint
;
public
static
void
main
(
String
[]
args
)
{
System
.
out
.
println
(
new
BCryptPasswordEncoder
().
encode
(
"123456"
));
}
/**
* 用于配置需要拦截的url路径、jwt过滤器及出异常后的处理器
*/
@Override
protected
void
configure
(
HttpSecurity
http
)
throws
Exception
{
String
loginPath
=
Constants
.
REQUEST_PREFIX
+
"/login"
;
http
.
cors
().
and
()
// 开启cors跨域
.
csrf
().
disable
()
// 禁用csrf 由于使用的是JWT,我们这里不需要csrf
.
exceptionHandling
()
.
authenticationEntryPoint
(
customAuthenticationEntryPoint
)
// 自定义401认证异常响应数据 用来解决匿名用户访问无权限资源时的异常
.
accessDeniedHandler
(
accessDeniedHandler
()).
and
()
// 自定义403授权异常响应数据 拒绝访问
.
sessionManagement
().
sessionCreationPolicy
(
SessionCreationPolicy
.
STATELESS
).
and
()
// 基于token 不需要session
.
authorizeRequests
()
// 限定签名成功的请求
.
antMatchers
(
HttpMethod
.
OPTIONS
).
permitAll
()
// 跨域请求会先进行一次options请求
.
antMatchers
(
antPaths
.
split
(
","
)).
permitAll
()
// 放行不需要认证的url
.
antMatchers
(
HttpMethod
.
POST
,
loginPath
).
permitAll
()
// 允许POST类型登录接口
//.antMatchers("/**").permitAll() // 测试时全部运行访问
.
anyRequest
().
authenticated
()
// 除上面外的所有请求全部需要鉴权认证
.
and
()
// 添加*/login登录请求过滤器
.
addFilterBefore
(
new
JwtLoginFilter
(
loginPath
,
authenticationManager
()),
UsernamePasswordAuthenticationFilter
.
class
)
// 过滤其他请求以检查JWT在header中的存在
.
addFilterBefore
(
new
JwtAuthenticationFilter
(),
UsernamePasswordAuthenticationFilter
.
class
);
}
@Bean
public
UserDetailsService
customUserDetailsService
()
{
return
new
CustomUserDetailsService
();
}
/**
* 用于配置UserDetailsService及PasswordEncode
*/
@Override
public
void
configure
(
AuthenticationManagerBuilder
auth
)
throws
Exception
{
auth
.
userDetailsService
(
customUserDetailsService
())
.
passwordEncoder
(
passwordEncoder
());
//对密码的加密处理,如果user中密码没有加密,则可以不加此方法。注意加密请使用security自带的加密方式。
}
@Bean
public
PasswordEncoder
passwordEncoder
()
{
return
new
BCryptPasswordEncoder
();
}
@Bean
(
name
=
BeanIds
.
AUTHENTICATION_MANAGER
)
@Override
public
AuthenticationManager
authenticationManagerBean
()
throws
Exception
{
return
super
.
authenticationManagerBean
();
}
@Bean
public
AccessDeniedHandler
accessDeniedHandler
()
{
return
new
CustomAccessDeniedHandler
();
}
}
admin/src/main/java/com/onsiteservice/admin/security/SecurityService.java
0 → 100644
View file @
239f7354
package
com
.
onsiteservice
.
admin
.
security
;
import
com.alibaba.fastjson.JSONObject
;
import
com.onsiteservice.admin.security.pojo.CustomUserDetails
;
import
com.onsiteservice.constant.constant.Constants
;
import
com.onsiteservice.core.security.jwt.JwtManager
;
import
com.onsiteservice.dao.mapper.sys.SysUserMapper
;
import
com.onsiteservice.entity.sys.SysUser
;
import
com.onsiteservice.util.ArrayUtils
;
import
com.onsiteservice.util.ReflectUtils
;
import
io.jsonwebtoken.Claims
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.security.access.ConfigAttribute
;
import
org.springframework.security.access.SecurityConfig
;
import
org.springframework.security.web.util.matcher.AntPathRequestMatcher
;
import
org.springframework.stereotype.Service
;
import
org.springframework.util.AntPathMatcher
;
import
tk.mybatis.mapper.entity.Condition
;
import
javax.annotation.Resource
;
import
javax.servlet.http.HttpServletRequest
;
import
java.util.*
;
/**
* 具体模块安全通用服务
*/
@Service
@Slf4j
public
class
SecurityService
{
@Resource
private
SysUserMapper
sysUserMapper
;
@Resource
private
HttpServletRequest
httpServletRequest
;
@Value
(
"${project.admin-security.ant-paths}"
)
private
String
antPaths
;
/**
* 根据用户名获取用户信息
*/
public
Object
getUserByName
(
String
userName
)
{
Condition
condition
=
new
Condition
(
SysUser
.
class
);
condition
.
createCriteria
().
andEqualTo
(
JwtManager
.
USER_NAME
,
userName
);
return
sysUserMapper
.
selectByCondition
(
condition
).
stream
().
findFirst
().
orElse
(
null
);
}
/**
* 验证权限资源列表中所有权限
*/
public
boolean
verifyPermissions
(
HttpServletRequest
request
,
List
resourceList
)
{
if
(
isIgnorePath
(
request
.
getRequestURI
()))
{
return
true
;
}
String
method
;
AntPathRequestMatcher
matcher
;
if
(
resourceList
!=
null
)
{
for
(
Object
item
:
resourceList
)
{
String
operatePath
=
ReflectUtils
.
invokeGetter
(
item
,
"operatePath"
);
String
operateMethod
=
ReflectUtils
.
invokeGetter
(
item
,
"operateMethod"
);
matcher
=
new
AntPathRequestMatcher
(
Constants
.
REQUEST_PREFIX
+
operatePath
);
method
=
operateMethod
==
null
?
"ALL"
:
operateMethod
.
toUpperCase
();
if
(
matcher
.
matches
(
request
))
{
//当权限表权限的method为ALL时表示拥有此路径的所有请求方式权利
if
(
method
.
equals
(
request
.
getMethod
())
||
"ALL"
.
equals
(
method
))
{
return
true
;
}
}
}
}
return
false
;
}
/**
* 判断请求资源是否时可忽略权限检查
*/
private
boolean
isIgnorePath
(
String
path
)
{
if
(
antPaths
!=
null
)
{
for
(
String
pattern
:
StringUtils
.
deleteWhitespace
(
antPaths
).
split
(
","
))
{
// Ant URL风格匹配
AntPathMatcher
antPathMatcher
=
new
AntPathMatcher
();
if
(
antPathMatcher
.
match
(
pattern
,
path
))
{
return
true
;
}
return
false
;
}
}
return
false
;
}
}
admin/src/main/java/com/onsiteservice/admin/security/authentication/CustomUserDetailsService.java
0 → 100644
View file @
239f7354
package
com
.
onsiteservice
.
admin
.
security
.
authentication
;
import
com.onsiteservice.admin.security.SecurityService
;
import
com.onsiteservice.admin.security.pojo.CustomUserDetails
;
import
com.onsiteservice.util.ReflectUtils
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.ObjectUtils
;
import
org.springframework.security.authentication.AuthenticationCredentialsNotFoundException
;
import
org.springframework.security.authentication.DisabledException
;
import
org.springframework.security.core.userdetails.UserDetails
;
import
org.springframework.security.core.userdetails.UserDetailsService
;
import
javax.annotation.Resource
;
import
java.util.ArrayList
;
/**
* @author 潘维吉
* @date 2020/3/5 13:57
* @email 406798106@qq.com
* @description 自定义用户详情服务实现
*/
@Slf4j
public
class
CustomUserDetailsService
implements
UserDetailsService
{
@Resource
private
SecurityService
securityService
;
/**
* 提供一种从用户名可以查到用户并返回的方法 每次登陆调用
* 用户名attemptAuthentication方法传入
*/
@Override
public
UserDetails
loadUserByUsername
(
String
userName
)
{
log
.
info
(
"2. CustomUserDetailsService.loadUserByUsername"
);
Object
user
=
securityService
.
getUserByName
(
userName
);
// 出现异常会在unsuccessfulAuthentication方法处理响应数据
if
(
ObjectUtils
.
isEmpty
(
user
))
{
throw
new
AuthenticationCredentialsNotFoundException
(
"用户名不存在"
);
}
if
(!(
Boolean
)
ReflectUtils
.
invokeGetter
(
user
,
CustomUserDetails
.
IS_ENABLED
))
{
throw
new
DisabledException
(
"账号已被禁用"
);
}
return
new
CustomUserDetails
(
user
,
new
ArrayList
<>());
}
}
admin/src/main/java/com/onsiteservice/admin/security/authentication/JwtAuthenticationFilter.java
0 → 100644
View file @
239f7354
package
com
.
onsiteservice
.
admin
.
security
.
authentication
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.onsiteservice.constant.constant.Constants
;
import
com.onsiteservice.core.security.jwt.JwtManager
;
import
com.onsiteservice.core.security.jwt.JwtPathProperties
;
import
io.jsonwebtoken.Claims
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.core.context.SecurityContextHolder
;
import
org.springframework.web.filter.GenericFilterBean
;
import
javax.servlet.FilterChain
;
import
javax.servlet.ServletException
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.ServletResponse
;
import
javax.servlet.http.HttpServletRequest
;
import
java.io.IOException
;
import
java.util.Collections
;
/**
* JWT认证过滤器加入 spring security 管理
*/
@Slf4j
public
class
JwtAuthenticationFilter
extends
GenericFilterBean
{
@Override
public
void
doFilter
(
ServletRequest
request
,
ServletResponse
response
,
FilterChain
filterChain
)
throws
IOException
,
ServletException
{
Authentication
authentication
=
this
.
getAuthentication
((
HttpServletRequest
)
request
);
SecurityContextHolder
.
getContext
().
setAuthentication
(
authentication
);
filterChain
.
doFilter
(
request
,
response
);
}
/**
* 解析token 从令牌中获取数据声明 除登录外 每次请求都会调用
* 将用户id存到request中 用于注解获取当前用户id
*
* @param request
*/
private
Authentication
getAuthentication
(
HttpServletRequest
request
)
{
log
.
info
(
"4. JwtAuthenticationFilter.getAuthentication"
);
if
(!
JwtPathProperties
.
isAuth
(
request
.
getRequestURI
()))
{
// JWT白名单放行
// log.info("JWT白名单放行不认证: {}", request.getRequestURI());
return
null
;
}
else
{
try
{
String
token
=
request
.
getHeader
(
JwtManager
.
AUTHORIZATION_HEADER
);
// 返回401错误
if
(
StringUtils
.
isBlank
(
token
))
{
throw
new
RuntimeException
();
}
Claims
claims
=
JwtManager
.
parseToken
(
token
.
replace
(
JwtManager
.
BEARER
,
""
));
if
(
claims
!=
null
)
{
JSONObject
jsonObject
=
JSON
.
parseObject
(
claims
.
getSubject
());
// 如果token验证成功,将token对应的用户id
Object
userId
=
jsonObject
.
get
(
JwtManager
.
USER_ID
);
// 如果token验证成功,将token对应的用户id存在request中,便于之后注入
request
.
setAttribute
(
Constants
.
CURRENT_USER_ID
,
userId
);
// 如果token验证成功,将token对应的用户名
String
userName
=
(
String
)
jsonObject
.
get
(
JwtManager
.
USER_NAME
);
if
(
userName
!=
null
)
{
return
new
UsernamePasswordAuthenticationToken
(
userName
,
null
,
Collections
.
emptyList
());
}
}
return
null
;
}
catch
(
Exception
e
)
{
log
.
error
(
"从令牌中获取数据声明异常: {}"
,
e
.
getMessage
());
return
null
;
}
}
}
}
admin/src/main/java/com/onsiteservice/admin/security/authentication/JwtLoginFilter.java
0 → 100644
View file @
239f7354
package
com
.
onsiteservice
.
admin
.
security
.
authentication
;
import
com.alibaba.fastjson.JSON
;
import
com.onsiteservice.admin.security.pojo.AccountCredentials
;
import
com.onsiteservice.admin.security.pojo.CustomUserDetails
;
import
com.onsiteservice.admin.security.pojo.TokenTimeProperties
;
import
com.onsiteservice.admin.security.pojo.TokenVO
;
import
com.onsiteservice.core.config.MvcConfig
;
import
com.onsiteservice.core.result.Result
;
import
com.onsiteservice.core.security.jwt.JwtManager
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.security.authentication.AuthenticationManager
;
import
org.springframework.security.authentication.InternalAuthenticationServiceException
;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.core.AuthenticationException
;
import
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter
;
import
org.springframework.security.web.util.matcher.AntPathRequestMatcher
;
import
javax.servlet.FilterChain
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
import
java.util.Collections
;
import
java.util.Map
;
import
java.util.Objects
;
import
static
com
.
onsiteservice
.
core
.
result
.
ResultGenerator
.
failCustom
;
import
static
com
.
onsiteservice
.
core
.
result
.
ResultGenerator
.
success
;
import
static
org
.
springframework
.
http
.
HttpStatus
.
UNAUTHORIZED
;
/**
* @author 潘维吉
* @date 2020/3/6 10:03
* @email 406798106@qq.com
* @description 将JWT添加到我们的身份验证过程
*/
@Slf4j
public
class
JwtLoginFilter
extends
AbstractAuthenticationProcessingFilter
{
public
JwtLoginFilter
(
String
url
,
AuthenticationManager
authManager
)
{
super
(
new
AntPathRequestMatcher
(
url
));
setAuthenticationManager
(
authManager
);
}
/**
* 首先过滤器会调用自身的attemptAuthentication方法,从request中取出authentication,
* authentication是在SecurityContextPersistenceFilter过滤器中通过捕获用户提交的登录表单中的内容生成的一个Authentication接口实例
* 拿到authentication对象后,过滤器会调用authenticate认证授权方法,并传入该对象
*/
@Override
public
Authentication
attemptAuthentication
(
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
AuthenticationException
,
IOException
{
log
.
info
(
"1. JwtLoginFilter.attemptAuthentication"
);
AccountCredentials
account
=
JSON
.
parseObject
(
request
.
getInputStream
(),
AccountCredentials
.
class
);
request
.
setAttribute
(
"rememberMe"
,
account
.
getRememberMe
());
UsernamePasswordAuthenticationToken
token
=
new
UsernamePasswordAuthenticationToken
(
account
.
getUserName
(),
account
.
getPassword
(),
Collections
.
emptyList
());
return
getAuthenticationManager
().
authenticate
(
token
);
}
/**
* 认证成功 响应数据
*/
@Override
protected
void
successfulAuthentication
(
HttpServletRequest
request
,
HttpServletResponse
response
,
FilterChain
chain
,
Authentication
auth
)
{
log
.
info
(
"3. JwtLoginFilter.successfulAuthentication"
);
Object
rmObj
=
request
.
getAttribute
(
"rememberMe"
);
boolean
rememberMe
=
rmObj
!=
null
&&
(
Boolean
)
rmObj
;
// Authentication 中包含 loadUserByUsername() 方法返回的自定义的用户数据信息
String
userName
=
auth
.
getName
();
Long
userId
=
((
CustomUserDetails
)
auth
.
getPrincipal
()).
getUserId
();
// 生成token 返回给前端
String
token
=
JwtManager
.
createToken
(
Map
.
of
(
JwtManager
.
USER_ID
,
userId
,
JwtManager
.
USER_NAME
,
userName
),
rememberMe
?
TokenTimeProperties
.
rememberExpiresTime
:
TokenTimeProperties
.
expiresTime
);
Result
result
=
success
(
TokenVO
.
builder
().
token
(
token
)
.
expiresTime
(
rememberMe
?
TokenTimeProperties
.
rememberExpiresTime
:
TokenTimeProperties
.
expiresTime
).
build
(),
"登录成功"
);
MvcConfig
.
responseResult
(
response
,
result
);
}
/**
* 认证失败 响应数据
*/
@Override
protected
void
unsuccessfulAuthentication
(
HttpServletRequest
request
,
HttpServletResponse
response
,
AuthenticationException
exception
)
{
log
.
info
(
"3. JwtLoginFilter.unsuccessfulAuthentication"
);
exception
.
printStackTrace
();
String
msg
=
(
exception
instanceof
InternalAuthenticationServiceException
)
?
exception
.
getMessage
()
:
"用户名或密码错误"
;
Result
result
=
failCustom
(
UNAUTHORIZED
.
value
(),
msg
);
MvcConfig
.
responseResult
(
response
,
result
);
}
}
admin/src/main/java/com/onsiteservice/admin/security/handler/CustomAccessDeniedHandler.java
0 → 100644
View file @
239f7354
package
com
.
onsiteservice
.
admin
.
security
.
handler
;
import
com.onsiteservice.core.config.MvcConfig
;
import
com.onsiteservice.core.result.Result
;
import
org.springframework.security.access.AccessDeniedException
;
import
org.springframework.security.web.access.AccessDeniedHandler
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
static
com
.
onsiteservice
.
core
.
result
.
ResultGenerator
.
failCustom
;
import
static
org
.
springframework
.
http
.
HttpStatus
.
FORBIDDEN
;
/**
* @author 潘维吉
* @date 2020/3/7 10:29
* @email 406798106@qq.com
* @description 自定义返异常回信息 当用户没有访问权限时的处理器
*/
public
class
CustomAccessDeniedHandler
implements
AccessDeniedHandler
{
@Override
public
void
handle
(
HttpServletRequest
request
,
HttpServletResponse
response
,
AccessDeniedException
accessDeniedException
)
{
Result
result
=
failCustom
(
FORBIDDEN
.
value
(),
"拒绝访问"
);
MvcConfig
.
responseResult
(
response
,
result
);
}
}
admin/src/main/java/com/onsiteservice/admin/security/handler/CustomAuthenticationEntryPoint.java
0 → 100644
View file @
239f7354
package
com
.
onsiteservice
.
admin
.
security
.
handler
;
import
com.onsiteservice.core.config.MvcConfig
;
import
com.onsiteservice.core.result.Result
;
import
org.springframework.security.core.AuthenticationException
;
import
org.springframework.security.web.AuthenticationEntryPoint
;
import
org.springframework.stereotype.Component
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
static
com
.
onsiteservice
.
core
.
result
.
ResultGenerator
.
failCustom
;
import
static
org
.
springframework
.
http
.
HttpStatus
.
UNAUTHORIZED
;
/**
* @author 潘维吉
* @date 2020/3/5 16:22
* @email 406798106@qq.com
* @description 未通过认证的用户请求受保护资源时调用 用来解决匿名用户访问无权限资源时的异常
* 当未登录或者token失效访问接口时,自定义的返回结果
*/
@Component
public
class
CustomAuthenticationEntryPoint
implements
AuthenticationEntryPoint
{
@Override
public
void
commence
(
HttpServletRequest
request
,
HttpServletResponse
response
,
AuthenticationException
authException
)
{
// 当用户试图在不提供任何凭据的情况下访问受保护的REST资源时,将调用此方法
// 我们应该发送一个未经认证的401响应,因为没有“登录页面”可以重定向到
Result
result
=
failCustom
(
UNAUTHORIZED
.
value
(),
"没有访问权限"
);
MvcConfig
.
responseResult
(
response
,
result
);
}
}
admin/src/main/java/com/onsiteservice/admin/security/pojo/AccountCredentials.java
0 → 100644
View file @
239f7354
package
com
.
onsiteservice
.
admin
.
security
.
pojo
;
import
lombok.Getter
;
import
lombok.Setter
;
/**
* @author 潘维吉
* @date 2020/3/6 10:07
* @email 406798106@qq.com
* @description 前端登录请求数据
*/
@Getter
@Setter
public
class
AccountCredentials
{
private
String
userName
;
private
String
password
;
private
Boolean
rememberMe
;
}
admin/src/main/java/com/onsiteservice/admin/security/pojo/CustomUserDetails.java
0 → 100644
View file @
239f7354
package
com
.
onsiteservice
.
admin
.
security
.
pojo
;
import
com.onsiteservice.util.ReflectUtils
;
import
lombok.Getter
;
import
org.springframework.security.core.GrantedAuthority
;
import
org.springframework.security.core.userdetails.User
;
import
java.util.Collection
;
/**
* @author 潘维吉
* @date 2020/3/5 13:57
* @email 406798106@qq.com
* @description 自定义用户信息 用于直接返回更多数据给前端 用户信息和权限
*/
@Getter
public
class
CustomUserDetails
extends
User
{
/**
* 业务系统自定义用户实体属性 根据业务命名定义修改
*/
public
static
final
String
ID
=
"id"
;
public
static
final
String
COMPANY_ID
=
"companyId"
;
public
static
final
String
USERNAME
=
"userName"
;
public
static
final
String
REAL_NAME
=
"realName"
;
public
static
final
String
PASSWORD
=
"password"
;
public
static
final
String
AVATAR
=
"avatarUrl"
;
public
static
final
String
IS_ENABLED
=
"isEnabled"
;
public
static
final
String
IS_GOD
=
"isGod"
;
public
static
final
String
IS_SUPER_GOD
=
"isSuperGod"
;
private
static
final
long
serialVersionUID
=
1167013428315310807L
;
private
Long
userId
;
private
Long
companyId
;
private
String
realName
;
private
String
avatarUrl
;
//private List permissionList;
public
CustomUserDetails
(
String
username
,
String
password
,
Collection
<?
extends
GrantedAuthority
>
authorities
)
{
super
(
username
,
password
,
authorities
);
}
public
CustomUserDetails
(
Object
user
,
Collection
<?
extends
GrantedAuthority
>
authorities
)
{
super
(
ReflectUtils
.
invokeGetter
(
user
,
USERNAME
),
ReflectUtils
.
invokeGetter
(
user
,
PASSWORD
),
authorities
);
this
.
userId
=
ReflectUtils
.
invokeGetter
(
user
,
ID
);
this
.
companyId
=
ReflectUtils
.
invokeGetter
(
user
,
COMPANY_ID
);
this
.
realName
=
ReflectUtils
.
invokeGetter
(
user
,
REAL_NAME
);
this
.
avatarUrl
=
ReflectUtils
.
invokeGetter
(
user
,
AVATAR
);
}
public
CustomUserDetails
(
String
username
,
String
password
,
boolean
enabled
,
boolean
accountNonExpired
,
boolean
credentialsNonExpired
,
boolean
accountNonLocked
,
Collection
<?
extends
GrantedAuthority
>
authorities
)
{
super
(
username
,
password
,
enabled
,
accountNonExpired
,
credentialsNonExpired
,
accountNonLocked
,
authorities
);
}
}
admin/src/main/java/com/onsiteservice/admin/security/pojo/TokenTimeProperties.java
0 → 100644
View file @
239f7354
package
com
.
onsiteservice
.
admin
.
security
.
pojo
;
/**
* @author 潘维吉
* @date 2020/3/6 16:52
* @email 406798106@qq.com
* @description 过滤器中获取配置参数
*/
public
class
TokenTimeProperties
{
/**
* 默认token有效时间 秒
*/
public
static
long
expiresTime
=
172800
;
/**
* 使用记住我模式token有效时间 秒
*/
public
static
long
rememberExpiresTime
=
864000
;
}
admin/src/main/java/com/onsiteservice/admin/security/pojo/TokenVO.java
0 → 100644
View file @
239f7354
package
com
.
onsiteservice
.
admin
.
security
.
pojo
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Builder
;
import
lombok.Getter
;
import
lombok.Setter
;
import
lombok.ToString
;
/**
* @author 潘维吉
* @date 2020/1/15 15:41
* @email 406798106@qq.com
* @description 令牌VO
*/
@ApiModel
(
description
=
"Token接口响应数据"
)
@Builder
@Getter
@Setter
@ToString
public
class
TokenVO
{
/**
* 令牌Token
*/
@ApiModelProperty
(
"令牌Token"
)
private
String
token
;
/**
* Token过期时间
*/
@ApiModelProperty
(
value
=
"Token过期时间(秒)"
,
example
=
"-1"
)
private
Long
expiresTime
;
}
admin/src/main/java/com/onsiteservice/admin/security/pojo/spring-security.png
0 → 100644
View file @
239f7354
266 KB
admin/src/main/resources/application-dev.yaml
View file @
239f7354
admin/src/main/resources/application-prod.yaml
View file @
239f7354
# 生产环境配置
spring
:
profiles
:
include
:
-
common-prod
#
#logging:
# config: classpath:logback-spring-prod.xml
project
:
swagger
:
enabled
:
false
admin/src/main/resources/application-sit.yaml
deleted
100644 → 0
View file @
f94d388b
# 联调环境配置
spring
:
profiles
:
include
:
-
common-sit
admin/src/main/resources/application-test.yaml
deleted
100644 → 0
View file @
f94d388b
# 测试环境配置
spring
:
profiles
:
include
:
-
common-test
admin/src/main/resources/application.yaml
View file @
239f7354
...
...
@@ -27,4 +27,3 @@ spring:
-
common
application
:
name
:
onsite-service-admin
\ No newline at end of file
admin/src/test/java/com/onsiteservice/admin/JasyptTest.java
View file @
239f7354
...
...
@@ -3,6 +3,7 @@ package com.onsiteservice.admin;
import
org.jasypt.encryption.StringEncryptor
;
import
org.junit.jupiter.api.Test
;
import
org.springframework.boot.test.context.SpringBootTest
;
import
org.springframework.security.crypto.password.PasswordEncoder
;
import
javax.annotation.Resource
;
...
...
@@ -17,4 +18,11 @@ public class JasyptTest {
String
password
=
encryptor
.
encrypt
(
"antaikeji2022"
);
System
.
out
.
println
(
password
);
}
@Resource
private
PasswordEncoder
passwordEncoder
;
@Test
void
password
()
{
System
.
out
.
println
(
passwordEncoder
.
encode
(
"123"
));
}
}
common/pom.xml
View file @
239f7354
...
...
@@ -148,10 +148,10 @@
</dependency>-->
<!--微信公众号-->
<dependency>
<!--
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java-mp-spring-boot-starter</artifactId>
</dependency>
</dependency>
-->
<!--微信支付-->
<dependency>
<groupId>
com.github.binarywang
</groupId>
...
...
common/src/main/java/com/onsiteservice/common/annotation/limit/RateLimiterAspect.java
View file @
239f7354
...
...
@@ -43,7 +43,7 @@ public class RateLimiterAspect {
*/
private
Map
<
String
,
RateLimiter
>
limitMap
=
Maps
.
newConcurrentMap
();
@Pointcut
(
"@annotation(com.
monorepo
.common.annotation.limit.RateLimit)"
)
@Pointcut
(
"@annotation(com.
onsiteservice
.common.annotation.limit.RateLimit)"
)
public
void
rateLimit
()
{
}
...
...
common/src/main/java/com/onsiteservice/common/annotation/validation/UniqueCheckAspect.java
View file @
239f7354
...
...
@@ -24,7 +24,7 @@ import java.util.Objects;
@Component
public
class
UniqueCheckAspect
{
@Pointcut
(
"@annotation(com.
monorepo
.common.annotation.validation.Unique)"
)
@Pointcut
(
"@annotation(com.
onsiteservice
.common.annotation.validation.Unique)"
)
public
void
unique
()
{
}
...
...
common/src/main/java/com/onsiteservice/common/log/ServiceLogAspect.java
View file @
239f7354
...
...
@@ -28,7 +28,7 @@ public class ServiceLogAspect {
* @return 切入点返回值
* @throws Throwable 异常信息
*/
@Around
(
"@within(com.
monorepo.common.log.ServiceLog) ||@annotation(com.monorepo
.common.log.ServiceLog)"
)
@Around
(
"@within(com.
onsiteservice.common.log.ServiceLog) ||@annotation(com.onsiteservice
.common.log.ServiceLog)"
)
public
Object
doServiceLog
(
ProceedingJoinPoint
joinPoint
)
throws
Throwable
{
MethodSignature
signature
=
(
MethodSignature
)
joinPoint
.
getSignature
();
// 拦截的实体类
...
...
constant/src/main/resources/application-common-dev.yaml
View file @
239f7354
...
...
@@ -8,7 +8,7 @@ spring:
datasource
:
url
:
jdbc:mysql://39.96.84.51:3306/onsite_service_dev${project.mysql-url-params}
username
:
onsite_service
password
:
ENC(
dQhwSeQ6J1uCCW5zK8eBzFyES4nW0xw3
)
password
:
ENC(
oHHR1aTYVkDAYpWjQk2rD0qIqDId4m0l
)
redis
:
database
:
8
...
...
constant/src/main/resources/application-common-prod.yaml
View file @
239f7354
# 通用prod配置
server
:
# tomcat的ssl证书配置 启用https和http2 走nginx代理 nginx ssl配置即可
# http2:
# enabled: true
# ssl:
# key-store: classpath:app-api.com.pfx
# key-store-password:
# key-store-type: PKCS12
spring
:
profiles
:
include
:
-
third-service-prod
-
aliyun-sms-prod
# 数据源配置
datasource
:
url
:
jdbc:mysql://172.21.7.176:3306/wellness_unblocked${project.mysql-url-params}
username
:
wellness_unblocked
password
:
ENC(nNSzGODQTtkxJ9Rk9i2pngwzs+m+2wncypMAJ+HREg8=)
hikari
:
# 池中维护的最小空闲连接数 默认10
minimum-idle
:
10
# 池中最大连接数,包括闲置和使用中的连接 默认10
maximum-pool-size
:
200
# 一个连接的生命时长(毫秒),超时而且没被使用则被释放(retired),缺省:30分钟
max-lifetime
:
600000
# 一个连接idle状态的最大时长(毫秒),空闲连接数超过minimumIdle,而且空闲时间超过idleTimeout,则会被移除 缺省:10分钟
idle-timeout
:
60000
# 等待连接池分配连接的最大时长(毫秒),超过这个时长还没可用的连接则发生SQLException, 缺省:30秒
connection-timeout
:
30000
connection-test-query
:
SELECT 1
redis
:
database
:
1
# Redis服务器地址
host
:
172.21.7.176
password
:
antaikeji2020
rabbitmq
:
host
:
172.21.7.176
username
:
root
password
:
antaikeji2020
## 开启Swagger的Basic认证功能
knife4j
:
basic
:
enable
:
true
username
:
monorepo
password
:
antaikeji666
# 日志配置 默认仅在控制台打印log信息 将log信息记录到文件 指定logging.file或logging.path 日志文件在10Mb大小被截断,产生新的日志文件
logging
:
level
:
root
:
error
file
:
path
:
./logs
logback
:
rollingpolicy
:
max-file-size
:
20
max-history
:
3
# config: classpath:logback-spring.xml # 自定义更详细的日志规则
constant/src/main/resources/application-common-sit.yaml
deleted
100644 → 0
View file @
f94d388b
# 通用sit联调配置
spring
:
profiles
:
include
:
-
third-service-sit
-
aliyun-sms-dev
# 数据源配置
datasource
:
url
:
jdbc:mysql://39.96.84.51:3306/wellness_unblocked_dev${project.mysql-url-params}
username
:
wellness_unblocked
password
:
ENC(dQhwSeQ6J1uCCW5zK8eBzFyES4nW0xw3)
jpa
:
show-sql
:
true
open-in-view
:
false
redis
:
database
:
3
constant/src/main/resources/application-common-test.yaml
deleted
100644 → 0
View file @
f94d388b
# 通用test配置
spring
:
profiles
:
include
:
-
third-service-test
-
aliyun-sms-dev
# 数据源配置
datasource
:
url
:
jdbc:mysql://39.96.84.51:3306/wellness_unblocked_dev${project.mysql-url-params}
username
:
wellness_unblocked
password
:
ENC(dQhwSeQ6J1uCCW5zK8eBzFyES4nW0xw3)
hikari
:
# 池中维护的最小空闲连接数 默认10
minimum-idle
:
10
# 池中最大连接数,包括闲置和使用中的连接 默认10
maximum-pool-size
:
30
connection-timeout
:
30000
connection-test-query
:
SELECT 1
redis
:
database
:
4
constant/src/main/resources/application-common.yaml
View file @
239f7354
...
...
@@ -24,7 +24,7 @@ spring:
use-legacy-processing
:
true
profiles
:
include
:
-
onsite-service-
third-service
-
third-service
# 默认dev开发模式配置 prod生产模式配置java -jar xxx.jar --spring.profiles.active=prod
active
:
dev
...
...
constant/src/main/resources/application-third-service-prod.yaml
View file @
239f7354
# 第三方服务prod配置
# 阿里云配置
aliyun
:
access-key-id
:
LTAI5t5ivKZ3B2QPpyjVrg6Q
access-key-secret
:
btTTn9rQvh61e4Q327hdOLliXLlj9l
oss
:
enabled
:
true
endpoint
:
https://oss-cn-beijing.aliyuncs.com
bucket-name
:
wellness-unblocked-production
cdn-url
:
https://wellness-unblocked-production.oss-cn-beijing.aliyuncs.com/
default-avatar
:
https://health-base.oss-cn-beijing.aliyuncs.com/default-avatar.png
sms
:
enabled
:
true
sign
:
国济物业护护通
region-id
:
cn-beijing
time-out
:
1000
batch-size
:
500
# 批量发送个数
constant/src/main/resources/application-third-service-sit.yaml
deleted
100644 → 0
View file @
f94d388b
# 第三方服务联调sit配置
constant/src/main/resources/application-third-service-test.yaml
deleted
100644 → 0
View file @
f94d388b
# 第三方服务test配置
constant/src/main/resources/application-third-service.yaml
View file @
239f7354
...
...
@@ -23,9 +23,11 @@ aliyun:
# 微信配置
wx
:
mappid
:
wxdc9fe9e7aaeddac4
appid
:
wxa56f0845ca456bac
# 微信支付
pay
:
appId
:
${wx.miniapp.appid}
#微信公众号或者小程序等的appid
appId
:
wxa56f0845ca456bac
#微信公众号或者小程序等的appid
mchId
:
1602411974
#微信支付商户号
dao/src/main/java/com/onsiteservice/dao/common/schedule/ShedLockConfig.java
View file @
239f7354
package
com
.
onsiteservice
.
dao
.
common
.
schedule
;
/*
package com.monorepo.dao.common.schedule;
import net.javacrumbs.shedlock.core.LockProvider;
...
...
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