Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
pig_冷冷
Pig
提交
be9db232
Pig
项目概览
pig_冷冷
/
Pig
上一次同步 12 个月
通知
3
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Pig
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
be9db232
编写于
1月 15, 2022
作者:
L
lbw
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
♻
Refactoring code. close #I4QEY0 登录失败会加载2次失败处理方法
♻
Refactoring code. close #I4QEY0 登录失败会加载2次失败处理方法
上级
a6780cee
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
56 addition
and
172 deletion
+56
-172
pig-auth/src/main/java/com/pig4cloud/pig/auth/config/AuthorizationServerConfiguration.java
...oud/pig/auth/config/AuthorizationServerConfiguration.java
+16
-9
pig-auth/src/main/java/com/pig4cloud/pig/auth/config/WebSecurityConfiguration.java
...m/pig4cloud/pig/auth/config/WebSecurityConfiguration.java
+38
-9
pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/service/PigCustomAuthenticationProvider.java
...mon/security/service/PigCustomAuthenticationProvider.java
+0
-154
pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/service/PigUserDetailsServiceImpl.java
...ig/common/security/service/PigUserDetailsServiceImpl.java
+2
-0
未找到文件。
pig-auth/src/main/java/com/pig4cloud/pig/auth/config/AuthorizationServerConfiguration.java
浏览文件 @
be9db232
...
...
@@ -20,7 +20,6 @@ import com.pig4cloud.pig.common.core.constant.SecurityConstants;
import
com.pig4cloud.pig.common.security.component.PigWebResponseExceptionTranslator
;
import
com.pig4cloud.pig.common.security.grant.ResourceOwnerCustomeAppTokenGranter
;
import
com.pig4cloud.pig.common.security.service.PigClientDetailsService
;
import
com.pig4cloud.pig.common.security.service.PigCustomAuthenticationProvider
;
import
com.pig4cloud.pig.common.security.service.PigCustomTokenServices
;
import
com.pig4cloud.pig.common.security.service.PigUser
;
import
lombok.RequiredArgsConstructor
;
...
...
@@ -29,7 +28,6 @@ import org.springframework.context.annotation.Bean;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.http.HttpMethod
;
import
org.springframework.security.authentication.AuthenticationManager
;
import
org.springframework.security.crypto.password.PasswordEncoder
;
import
org.springframework.security.oauth2.common.DefaultOAuth2AccessToken
;
import
org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer
;
import
org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter
;
...
...
@@ -83,6 +81,10 @@ public class AuthorizationServerConfiguration extends AuthorizationServerConfigu
setTokenGranter
(
endpoints
);
}
/**
* 自定义 APP 认证类型
* @param endpoints AuthorizationServerEndpointsConfigurer
*/
private
void
setTokenGranter
(
AuthorizationServerEndpointsConfigurer
endpoints
)
{
// 获取默认授权类型
TokenGranter
tokenGranter
=
endpoints
.
getTokenGranter
();
...
...
@@ -95,6 +97,10 @@ public class AuthorizationServerConfiguration extends AuthorizationServerConfigu
endpoints
.
tokenGranter
(
compositeTokenGranter
);
}
/**
* token 生成接口输出增强
* @return TokenEnhancer
*/
@Bean
public
TokenEnhancer
tokenEnhancer
()
{
return
(
accessToken
,
authentication
)
->
{
...
...
@@ -116,6 +122,10 @@ public class AuthorizationServerConfiguration extends AuthorizationServerConfigu
};
}
/**
* 客户端信息加载处理
* @return ClientDetailsService
*/
@Bean
public
ClientDetailsService
pigClientDetailsService
()
{
PigClientDetailsService
clientDetailsService
=
new
PigClientDetailsService
(
dataSource
);
...
...
@@ -124,13 +134,10 @@ public class AuthorizationServerConfiguration extends AuthorizationServerConfigu
return
clientDetailsService
;
}
@Bean
public
PigCustomAuthenticationProvider
authenticationProvider
(
PasswordEncoder
passwordEncoder
)
{
PigCustomAuthenticationProvider
authenticationProvider
=
new
PigCustomAuthenticationProvider
();
authenticationProvider
.
setPasswordEncoder
(
passwordEncoder
);
return
authenticationProvider
;
}
/**
* token 核心处理
* @return tokenServices
*/
@Bean
public
PigCustomTokenServices
tokenServices
()
{
PigCustomTokenServices
tokenServices
=
new
PigCustomTokenServices
();
...
...
pig-auth/src/main/java/com/pig4cloud/pig/auth/config/WebSecurityConfiguration.java
浏览文件 @
be9db232
...
...
@@ -19,15 +19,19 @@ package com.pig4cloud.pig.auth.config;
import
com.pig4cloud.pig.common.security.grant.CustomAppAuthenticationProvider
;
import
com.pig4cloud.pig.common.security.handler.FormAuthenticationFailureHandler
;
import
com.pig4cloud.pig.common.security.handler.SsoLogoutSuccessHandler
;
import
lombok.RequiredArgsConstructor
;
import
lombok.SneakyThrows
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Primary
;
import
org.springframework.core.annotation.Order
;
import
org.springframework.security.authentication.AuthenticationManager
;
import
org.springframework.security.authentication.dao.DaoAuthenticationProvider
;
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.builders.WebSecurity
;
import
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
;
import
org.springframework.security.core.userdetails.UserDetailsService
;
import
org.springframework.security.crypto.factory.PasswordEncoderFactories
;
import
org.springframework.security.crypto.password.PasswordEncoder
;
import
org.springframework.security.web.authentication.AuthenticationFailureHandler
;
...
...
@@ -35,27 +39,40 @@ import org.springframework.security.web.authentication.logout.LogoutSuccessHandl
/**
* @author lengleng
* @date 20
19/2/1
认证相关配置
* @date 20
22/1/12
认证相关配置
*/
@Primary
@Order
(
90
)
@Configuration
@RequiredArgsConstructor
public
class
WebSecurityConfiguration
extends
WebSecurityConfigurerAdapter
{
private
final
UserDetailsService
pigUserDetailsService
;
@Override
@SneakyThrows
protected
void
configure
(
HttpSecurity
http
)
{
http
.
authenticationProvider
(
new
CustomAppAuthenticationProvider
())
//
.
formLogin
().
loginPage
(
"/token/login"
).
loginProcessingUrl
(
"/token/form"
)
http
.
formLogin
().
loginPage
(
"/token/login"
).
loginProcessingUrl
(
"/token/form"
)
.
failureHandler
(
authenticationFailureHandler
()).
and
().
logout
()
.
logoutSuccessHandler
(
logoutSuccessHandler
()).
deleteCookies
(
"JSESSIONID"
).
invalidateHttpSession
(
true
)
.
and
().
authorizeRequests
().
antMatchers
(
"/token/**"
,
"/actuator/**"
,
"/mobile/**"
).
permitAll
()
.
anyRequest
().
authenticated
().
and
().
csrf
().
disable
();
}
/**
* 自定义 provider 列表注入
* @param auth AuthenticationManagerBuilder
*/
@Override
public
void
configure
(
WebSecurity
web
)
{
web
.
ignoring
().
antMatchers
(
"/css/**"
);
protected
void
configure
(
AuthenticationManagerBuilder
auth
)
{
DaoAuthenticationProvider
daoAuthenticationProvider
=
new
DaoAuthenticationProvider
();
daoAuthenticationProvider
.
setPasswordEncoder
(
passwordEncoder
());
daoAuthenticationProvider
.
setUserDetailsService
(
pigUserDetailsService
);
// 处理默认的密码模式认证
auth
.
authenticationProvider
(
daoAuthenticationProvider
);
// 自定义的认证模式
auth
.
authenticationProvider
(
new
CustomAppAuthenticationProvider
());
}
@Bean
...
...
@@ -65,13 +82,26 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
return
super
.
authenticationManagerBean
();
}
/**
* 认证中心静态资源处理
* @param web WebSecurity
*/
@Override
public
void
configure
(
WebSecurity
web
)
{
web
.
ignoring
().
antMatchers
(
"/css/**"
);
}
/**
* sso 表单登录失败处理
* @return FormAuthenticationFailureHandler
*/
@Bean
public
AuthenticationFailureHandler
authenticationFailureHandler
()
{
return
new
FormAuthenticationFailureHandler
();
}
/**
*
支持SSO 退出
*
SSO 退出逻辑处理
* @return LogoutSuccessHandler
*/
@Bean
...
...
@@ -80,9 +110,8 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
}
/**
* https://spring.io/blog/2017/11/01/spring-security-5-0-0-rc1-released#password-storage-updated
* Encoded password does not look like BCrypt
* @return PasswordEncoder
* 密码处理器
* @return 动态密码处理器 {类型}密文
*/
@Bean
public
PasswordEncoder
passwordEncoder
()
{
...
...
pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/service/PigCustomAuthenticationProvider.java
已删除
100644 → 0
浏览文件 @
a6780cee
package
com.pig4cloud.pig.common.security.service
;
import
cn.hutool.extra.spring.SpringUtil
;
import
org.springframework.core.Ordered
;
import
org.springframework.security.authentication.BadCredentialsException
;
import
org.springframework.security.authentication.InternalAuthenticationServiceException
;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken
;
import
org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.core.AuthenticationException
;
import
org.springframework.security.core.context.SecurityContextHolder
;
import
org.springframework.security.core.userdetails.UserDetails
;
import
org.springframework.security.core.userdetails.UserDetailsPasswordService
;
import
org.springframework.security.core.userdetails.UsernameNotFoundException
;
import
org.springframework.security.crypto.factory.PasswordEncoderFactories
;
import
org.springframework.security.crypto.password.PasswordEncoder
;
import
org.springframework.util.Assert
;
import
java.util.Comparator
;
import
java.util.Map
;
import
java.util.Optional
;
/**
* @author lengleng
* @date 2021/12/21
*
* 自定义 AuthenticationProvider 方便多用户体系
*/
public
class
PigCustomAuthenticationProvider
extends
AbstractUserDetailsAuthenticationProvider
{
/**
* The plaintext password used to perform PasswordEncoder#matches(CharSequence,
* String)} on when the user is not found to avoid SEC-2056.
*/
private
static
final
String
USER_NOT_FOUND_PASSWORD
=
"userNotFoundPassword"
;
private
PasswordEncoder
passwordEncoder
;
/**
* The password used to perform {@link PasswordEncoder#matches(CharSequence, String)}
* on when the user is not found to avoid SEC-2056. This is necessary, because some
* {@link PasswordEncoder} implementations will short circuit if the password is not
* in a valid format.
*/
private
volatile
String
userNotFoundEncodedPassword
;
private
UserDetailsPasswordService
userDetailsPasswordService
;
public
PigCustomAuthenticationProvider
()
{
setPasswordEncoder
(
PasswordEncoderFactories
.
createDelegatingPasswordEncoder
());
}
@Override
@SuppressWarnings
(
"deprecation"
)
protected
void
additionalAuthenticationChecks
(
UserDetails
userDetails
,
UsernamePasswordAuthenticationToken
authentication
)
throws
AuthenticationException
{
if
(
authentication
.
getCredentials
()
==
null
)
{
this
.
logger
.
debug
(
"Failed to authenticate since no credentials provided"
);
throw
new
BadCredentialsException
(
this
.
messages
.
getMessage
(
"AbstractUserDetailsAuthenticationProvider.badCredentials"
,
"Bad credentials"
));
}
String
presentedPassword
=
authentication
.
getCredentials
().
toString
();
if
(!
this
.
passwordEncoder
.
matches
(
presentedPassword
,
userDetails
.
getPassword
()))
{
this
.
logger
.
debug
(
"Failed to authenticate since password does not match stored value"
);
throw
new
BadCredentialsException
(
this
.
messages
.
getMessage
(
"AbstractUserDetailsAuthenticationProvider.badCredentials"
,
"Bad credentials"
));
}
}
@Override
protected
final
UserDetails
retrieveUser
(
String
username
,
UsernamePasswordAuthenticationToken
authentication
)
throws
AuthenticationException
{
prepareTimingAttackProtection
();
try
{
// 此处已获得 客户端认证 获取对应 userDetailsService
Authentication
clientAuthentication
=
SecurityContextHolder
.
getContext
().
getAuthentication
();
String
clientId
=
clientAuthentication
.
getName
();
Map
<
String
,
PigUserDetailsService
>
userDetailsServiceMap
=
SpringUtil
.
getBeansOfType
(
PigUserDetailsService
.
class
);
Optional
<
PigUserDetailsService
>
optional
=
userDetailsServiceMap
.
values
().
stream
()
.
filter
(
service
->
service
.
support
(
clientId
)).
max
(
Comparator
.
comparingInt
(
Ordered:
:
getOrder
));
if
(!
optional
.
isPresent
())
{
throw
new
InternalAuthenticationServiceException
(
"UserDetailsService error , not register"
);
}
UserDetails
loadedUser
=
optional
.
get
().
loadUserByUsername
(
username
);
if
(
loadedUser
==
null
)
{
throw
new
InternalAuthenticationServiceException
(
"UserDetailsService returned null, which is an interface contract violation"
);
}
return
loadedUser
;
}
catch
(
UsernameNotFoundException
ex
)
{
mitigateAgainstTimingAttack
(
authentication
);
throw
ex
;
}
catch
(
InternalAuthenticationServiceException
ex
)
{
throw
ex
;
}
catch
(
Exception
ex
)
{
throw
new
InternalAuthenticationServiceException
(
ex
.
getMessage
(),
ex
);
}
}
@Override
protected
Authentication
createSuccessAuthentication
(
Object
principal
,
Authentication
authentication
,
UserDetails
user
)
{
boolean
upgradeEncoding
=
this
.
userDetailsPasswordService
!=
null
&&
this
.
passwordEncoder
.
upgradeEncoding
(
user
.
getPassword
());
if
(
upgradeEncoding
)
{
String
presentedPassword
=
authentication
.
getCredentials
().
toString
();
String
newPassword
=
this
.
passwordEncoder
.
encode
(
presentedPassword
);
user
=
this
.
userDetailsPasswordService
.
updatePassword
(
user
,
newPassword
);
}
return
super
.
createSuccessAuthentication
(
principal
,
authentication
,
user
);
}
private
void
prepareTimingAttackProtection
()
{
if
(
this
.
userNotFoundEncodedPassword
==
null
)
{
this
.
userNotFoundEncodedPassword
=
this
.
passwordEncoder
.
encode
(
USER_NOT_FOUND_PASSWORD
);
}
}
private
void
mitigateAgainstTimingAttack
(
UsernamePasswordAuthenticationToken
authentication
)
{
if
(
authentication
.
getCredentials
()
!=
null
)
{
String
presentedPassword
=
authentication
.
getCredentials
().
toString
();
this
.
passwordEncoder
.
matches
(
presentedPassword
,
this
.
userNotFoundEncodedPassword
);
}
}
/**
* Sets the PasswordEncoder instance to be used to encode and validate passwords. If
* not set, the password will be compared using
* {@link PasswordEncoderFactories#createDelegatingPasswordEncoder()}
* @param passwordEncoder must be an instance of one of the {@code PasswordEncoder}
* types.
*/
public
void
setPasswordEncoder
(
PasswordEncoder
passwordEncoder
)
{
Assert
.
notNull
(
passwordEncoder
,
"passwordEncoder cannot be null"
);
this
.
passwordEncoder
=
passwordEncoder
;
this
.
userNotFoundEncodedPassword
=
null
;
}
protected
PasswordEncoder
getPasswordEncoder
()
{
return
this
.
passwordEncoder
;
}
public
void
setUserDetailsPasswordService
(
UserDetailsPasswordService
userDetailsPasswordService
)
{
this
.
userDetailsPasswordService
=
userDetailsPasswordService
;
}
}
pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/service/PigUserDetailsServiceImpl.java
浏览文件 @
be9db232
...
...
@@ -26,6 +26,7 @@ import lombok.SneakyThrows;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.cache.Cache
;
import
org.springframework.cache.CacheManager
;
import
org.springframework.context.annotation.Primary
;
import
org.springframework.security.core.userdetails.UserDetails
;
/**
...
...
@@ -34,6 +35,7 @@ import org.springframework.security.core.userdetails.UserDetails;
* @author lengleng hccake
*/
@Slf4j
@Primary
@RequiredArgsConstructor
public
class
PigUserDetailsServiceImpl
implements
PigUserDetailsService
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录