Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
有来开源组织
youlai-mall
提交
84aa6da7
Y
youlai-mall
项目概览
有来开源组织
/
youlai-mall
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Y
youlai-mall
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
84aa6da7
编写于
6月 06, 2023
作者:
郝
郝先瑞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
refactor: 认证中心升级(临时提交勿clone)
上级
b019e6dd
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
310 addition
and
170 deletion
+310
-170
youlai-auth/src/main/java/com/youlai/auth/authentication/password/ResourceOwnerPasswordAuthenticationProvider.java
...password/ResourceOwnerPasswordAuthenticationProvider.java
+1
-1
youlai-auth/src/main/java/com/youlai/auth/authentication/password/ResourceOwnerPasswordAuthenticationToken.java
...on/password/ResourceOwnerPasswordAuthenticationToken.java
+1
-1
youlai-auth/src/main/java/com/youlai/auth/authentication/wechat/WechatAuthenticationConverter.java
.../authentication/wechat/WechatAuthenticationConverter.java
+129
-0
youlai-auth/src/main/java/com/youlai/auth/authentication/wechat/WechatAuthenticationProvider.java
...h/authentication/wechat/WechatAuthenticationProvider.java
+150
-60
youlai-auth/src/main/java/com/youlai/auth/authentication/wechat/WechatAuthenticationToken.java
...auth/authentication/wechat/WechatAuthenticationToken.java
+29
-42
youlai-auth/src/main/java/com/youlai/auth/authentication/wechat/WechatTokenGranter.java
...youlai/auth/authentication/wechat/WechatTokenGranter.java
+0
-66
未找到文件。
youlai-auth/src/main/java/com/youlai/auth/authentication/password/ResourceOwnerPasswordAuthenticationProvider.java
浏览文件 @
84aa6da7
...
...
@@ -98,7 +98,7 @@ public class ResourceOwnerPasswordAuthenticationProvider implements Authenticati
}
// 生成 access_token
// @formatter:off
// @formatter:off
DefaultOAuth2TokenContext
.
Builder
tokenContextBuilder
=
DefaultOAuth2TokenContext
.
builder
()
.
registeredClient
(
registeredClient
)
.
principal
(
usernamePasswordAuthentication
)
...
...
youlai-auth/src/main/java/com/youlai/auth/authentication/password/ResourceOwnerPasswordAuthenticationToken.java
浏览文件 @
84aa6da7
...
...
@@ -18,7 +18,7 @@ public class ResourceOwnerPasswordAuthenticationToken extends OAuth2Authorizatio
* @param clientPrincipal
* @param additionalParameters
*/
p
rotected
ResourceOwnerPasswordAuthenticationToken
(
p
ublic
ResourceOwnerPasswordAuthenticationToken
(
Authentication
clientPrincipal
,
@Nullable
Set
<
String
>
scopes
,
Map
<
String
,
Object
>
additionalParameters
...
...
youlai-auth/src/main/java/com/youlai/auth/authentication/wechat/WechatAuthenticationConverter.java
0 → 100644
浏览文件 @
84aa6da7
package
com.youlai.auth.authentication.wechat
;
import
cn.hutool.core.util.StrUtil
;
import
com.youlai.auth.authentication.password.ResourceOwnerPasswordAuthenticationToken
;
import
jakarta.servlet.http.HttpServletRequest
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.core.context.SecurityContextHolder
;
import
org.springframework.security.oauth2.core.AuthorizationGrantType
;
import
org.springframework.security.oauth2.core.OAuth2AuthenticationException
;
import
org.springframework.security.oauth2.core.OAuth2Error
;
import
org.springframework.security.oauth2.core.OAuth2ErrorCodes
;
import
org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames
;
import
org.springframework.security.web.authentication.AuthenticationConverter
;
import
org.springframework.util.LinkedMultiValueMap
;
import
org.springframework.util.MultiValueMap
;
import
org.springframework.util.StringUtils
;
import
java.util.Arrays
;
import
java.util.HashSet
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
/**
* 参数解析
*
* @see org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2AuthorizationCodeAuthenticationConverter
*/
public
class
WechatAuthenticationConverter
implements
AuthenticationConverter
{
public
static
final
String
ACCESS_TOKEN_REQUEST_ERROR_URI
=
"https://datatracker.ietf.org/doc/html/rfc6749#section-5.2"
;
@Override
public
Authentication
convert
(
HttpServletRequest
request
)
{
// grant_type (REQUIRED)
String
grantType
=
request
.
getParameter
(
OAuth2ParameterNames
.
GRANT_TYPE
);
if
(!
"wechat"
.
equals
(
grantType
))
{
return
null
;
}
MultiValueMap
<
String
,
String
>
parameters
=
getParameters
(
request
);
// scope (OPTIONAL)
String
scope
=
parameters
.
getFirst
(
OAuth2ParameterNames
.
SCOPE
);
if
(
StringUtils
.
hasText
(
scope
)
&&
parameters
.
get
(
OAuth2ParameterNames
.
SCOPE
).
size
()
!=
1
)
{
throwError
(
OAuth2ErrorCodes
.
INVALID_REQUEST
,
OAuth2ParameterNames
.
SCOPE
,
ACCESS_TOKEN_REQUEST_ERROR_URI
);
}
Set
<
String
>
requestedScopes
=
null
;
if
(
StringUtils
.
hasText
(
scope
))
{
requestedScopes
=
new
HashSet
<>(
Arrays
.
asList
(
StringUtils
.
delimitedListToStringArray
(
scope
,
" "
)));
}
// code (REQUIRED)
String
code
=
parameters
.
getFirst
(
"code"
);
if
(
StrUtil
.
isBlank
(
code
))
{
throwError
(
OAuth2ErrorCodes
.
INVALID_REQUEST
,
"code"
,
ACCESS_TOKEN_REQUEST_ERROR_URI
);
}
// encryptedData (REQUIRED)
String
encryptedData
=
parameters
.
getFirst
(
"encryptedData"
);
if
(
StrUtil
.
isBlank
(
encryptedData
))
{
throwError
(
OAuth2ErrorCodes
.
INVALID_REQUEST
,
"encryptedData"
,
ACCESS_TOKEN_REQUEST_ERROR_URI
);
}
// iv (REQUIRED)
String
iv
=
parameters
.
getFirst
(
"iv"
);
if
(
StrUtil
.
isBlank
(
iv
))
{
throwError
(
OAuth2ErrorCodes
.
INVALID_REQUEST
,
"iv"
,
ACCESS_TOKEN_REQUEST_ERROR_URI
);
}
Authentication
clientPrincipal
=
SecurityContextHolder
.
getContext
().
getAuthentication
();
if
(
clientPrincipal
==
null
)
{
throwError
(
OAuth2ErrorCodes
.
INVALID_REQUEST
,
OAuth2ErrorCodes
.
INVALID_CLIENT
,
ACCESS_TOKEN_REQUEST_ERROR_URI
);
}
Map
<
String
,
Object
>
additionalParameters
=
parameters
.
entrySet
()
.
stream
()
.
filter
(
e
->
!
e
.
getKey
().
equals
(
OAuth2ParameterNames
.
GRANT_TYPE
)
&&
!
e
.
getKey
().
equals
(
OAuth2ParameterNames
.
SCOPE
))
.
collect
(
Collectors
.
toMap
(
Map
.
Entry
::
getKey
,
e
->
e
.
getValue
().
get
(
0
)));
ResourceOwnerPasswordAuthenticationToken
resourceOwnerPasswordAuthenticationToken
=
new
ResourceOwnerPasswordAuthenticationToken
(
clientPrincipal
,
requestedScopes
,
additionalParameters
);
return
resourceOwnerPasswordAuthenticationToken
;
}
public
static
MultiValueMap
<
String
,
String
>
getParameters
(
HttpServletRequest
request
)
{
Map
<
String
,
String
[]>
parameterMap
=
request
.
getParameterMap
();
MultiValueMap
<
String
,
String
>
parameters
=
new
LinkedMultiValueMap
(
parameterMap
.
size
());
parameterMap
.
forEach
((
key
,
values
)
->
{
for
(
String
value
:
values
)
{
parameters
.
add
(
key
,
value
);
}
});
return
parameters
;
}
public
static
void
throwError
(
String
errorCode
,
String
parameterName
,
String
errorUri
)
{
OAuth2Error
error
=
new
OAuth2Error
(
errorCode
,
"OAuth 2.0 Parameter: "
+
parameterName
,
errorUri
);
throw
new
OAuth2AuthenticationException
(
error
);
}
}
youlai-auth/src/main/java/com/youlai/auth/authentication/wechat/WechatAuthenticationProvider.java
浏览文件 @
84aa6da7
package
com.youlai.auth.authentication.wechat
;
import
cn.binarywang.wx.miniapp.api.WxMaService
;
import
cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult
;
import
cn.binarywang.wx.miniapp.bean.WxMaUserInfo
;
import
cn.hutool.core.bean.BeanUtil
;
import
com.youlai.auth.userdetails.member.MemberUserDetailsServiceImpl
;
import
com.youlai.common.result.Result
;
import
com.youlai.common.result.ResultCode
;
import
com.youlai.mall.ums.api.MemberFeignClient
;
import
com.youlai.mall.ums.dto.MemberAuthDTO
;
import
com.youlai.mall.ums.dto.MemberDTO
;
import
lombok.Data
;
import
lombok.SneakyThrows
;
import
cn.hutool.core.lang.Assert
;
import
com.youlai.auth.authentication.password.ResourceOwnerPasswordAuthenticationToken
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.security.authentication.AuthenticationManager
;
import
org.springframework.security.authentication.AuthenticationProvider
;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.core.AuthenticationException
;
import
org.springframework.security.core.userdetails.UserDetails
;
import
org.springframework.security.core.userdetails.UserDetailsService
;
import
org.springframework.security.oauth2.core.*
;
import
org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames
;
import
org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames
;
import
org.springframework.security.oauth2.server.authorization.OAuth2Authorization
;
import
org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService
;
import
org.springframework.security.oauth2.server.authorization.OAuth2TokenType
;
import
org.springframework.security.oauth2.server.authorization.authentication.OAuth2AccessTokenAuthenticationToken
;
import
org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken
;
import
org.springframework.security.oauth2.server.authorization.client.RegisteredClient
;
import
org.springframework.security.oauth2.server.authorization.context.AuthorizationServerContextHolder
;
import
org.springframework.security.oauth2.server.authorization.token.DefaultOAuth2TokenContext
;
import
org.springframework.security.oauth2.server.authorization.token.OAuth2TokenContext
;
import
org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator
;
import
org.springframework.util.CollectionUtils
;
import
java.util.HashSet
;
import
java.security.Principal
;
import
java.util.*
;
import
java.util.stream.Collectors
;
/**
* 微信认证提供者
*
* @author
<a href="mailto:xianrui0365@163.com">haoxr</a>
* @since
2021/9/25
* @author
haoxr
* @since
3.0.0
*/
@
Data
@
Slf4j
public
class
WechatAuthenticationProvider
implements
AuthenticationProvider
{
private
UserDetailsService
userDetailsService
;
private
WxMaService
wxMaService
;
private
MemberFeignClient
memberFeignClient
;
/**
* 微信认证
*
* @param authentication
* @return
* @throws AuthenticationException
*/
@SneakyThrows
@Override
public
Authentication
authenticate
(
Authentication
authentication
)
throws
AuthenticationException
{
WechatAuthenticationToken
authenticationToken
=
(
WechatAuthenticationToken
)
authentication
;
String
code
=
(
String
)
authenticationToken
.
getPrincipal
();
WxMaJscode2SessionResult
sessionInfo
=
wxMaService
.
getUserService
().
getSessionInfo
(
code
);
String
openid
=
sessionInfo
.
getOpenid
();
Result
<
MemberAuthDTO
>
memberAuthResult
=
memberFeignClient
.
loadUserByOpenId
(
openid
);
// 微信用户不存在,注册成为新会员
if
(
memberAuthResult
!=
null
&&
ResultCode
.
USER_NOT_EXIST
.
getCode
().
equals
(
memberAuthResult
.
getCode
()))
{
String
sessionKey
=
sessionInfo
.
getSessionKey
();
String
encryptedData
=
authenticationToken
.
getEncryptedData
();
String
iv
=
authenticationToken
.
getIv
();
// 解密 encryptedData 获取用户信息
WxMaUserInfo
userInfo
=
wxMaService
.
getUserService
().
getUserInfo
(
sessionKey
,
encryptedData
,
iv
);
MemberDTO
memberDTO
=
new
MemberDTO
();
BeanUtil
.
copyProperties
(
userInfo
,
memberDTO
);
memberDTO
.
setOpenid
(
openid
);
memberFeignClient
.
addMember
(
memberDTO
);
private
static
final
String
ERROR_URI
=
"https://datatracker.ietf.org/doc/html/rfc6749#section-5.2"
;
private
final
AuthenticationManager
authenticationManager
;
private
final
OAuth2AuthorizationService
authorizationService
;
private
final
OAuth2TokenGenerator
<?
extends
OAuth2Token
>
tokenGenerator
;
/**
* Constructs an {@code OAuth2ResourceOwnerPasswordAuthenticationProviderNew} using the provided parameters.
*
* @param authenticationManager the authentication manager
* @param authorizationService the authorization service
* @param tokenGenerator the token generator
* @since 0.2.3
*/
public
WechatAuthenticationProvider
(
AuthenticationManager
authenticationManager
,
OAuth2AuthorizationService
authorizationService
,
OAuth2TokenGenerator
<?
extends
OAuth2Token
>
tokenGenerator
)
{
Assert
.
notNull
(
authorizationService
,
"authorizationService cannot be null"
);
Assert
.
notNull
(
tokenGenerator
,
"tokenGenerator cannot be null"
);
this
.
authenticationManager
=
authenticationManager
;
this
.
authorizationService
=
authorizationService
;
this
.
tokenGenerator
=
tokenGenerator
;
}
UserDetails
userDetails
=
((
MemberUserDetailsServiceImpl
)
userDetailsService
).
loadUserByOpenId
(
openid
);
WechatAuthenticationToken
result
=
new
WechatAuthenticationToken
(
userDetails
,
new
HashSet
<>());
result
.
setDetails
(
authentication
.
getDetails
());
return
result
;
}
@Override
public
Authentication
authenticate
(
Authentication
authentication
)
throws
AuthenticationException
{
ResourceOwnerPasswordAuthenticationToken
authenticationToken
=
(
ResourceOwnerPasswordAuthenticationToken
)
authentication
;
// 验证客户端是否已认证
OAuth2ClientAuthenticationToken
clientPrincipal
=
getAuthenticatedClientElseThrowInvalidClient
(
authenticationToken
);
RegisteredClient
registeredClient
=
clientPrincipal
.
getRegisteredClient
();
// 验证客户端是否支持(grant_type=password)授权模式
if
(!
registeredClient
.
getAuthorizationGrantTypes
().
contains
(
AuthorizationGrantType
.
PASSWORD
))
{
throw
new
OAuth2AuthenticationException
(
OAuth2ErrorCodes
.
UNAUTHORIZED_CLIENT
);
}
// 密码验证
Map
<
String
,
Object
>
additionalParameters
=
authenticationToken
.
getAdditionalParameters
();
String
username
=
(
String
)
additionalParameters
.
get
(
"code"
);
String
encryptedData
=
(
String
)
additionalParameters
.
get
(
"encryptedData"
);
String
iv
=
(
String
)
additionalParameters
.
get
(
"iv"
);
UsernamePasswordAuthenticationToken
passwordAuthenticationToken
=
new
UsernamePasswordAuthenticationToken
(
username
,
password
);
log
.
debug
(
"got usernamePasswordAuthenticationToken="
+
passwordAuthenticationToken
);
Authentication
usernamePasswordAuthentication
=
authenticationManager
.
authenticate
(
passwordAuthenticationToken
);
usernamePasswordAuthentication
.
setAuthenticated
(
true
);
// 生成 access_token
// @formatter:off
DefaultOAuth2TokenContext
.
Builder
tokenContextBuilder
=
DefaultOAuth2TokenContext
.
builder
()
.
registeredClient
(
registeredClient
)
.
principal
(
usernamePasswordAuthentication
)
.
authorizationServerContext
(
AuthorizationServerContextHolder
.
getContext
())
.
authorizationGrantType
(
AuthorizationGrantType
.
PASSWORD
)
.
authorizationGrant
(
passwordAuthenticationToken
);
// @formatter:on
// ----- Access token -----
OAuth2TokenContext
tokenContext
=
tokenContextBuilder
.
tokenType
(
OAuth2TokenType
.
ACCESS_TOKEN
).
build
();
OAuth2Token
generatedAccessToken
=
this
.
tokenGenerator
.
generate
(
tokenContext
);
if
(
generatedAccessToken
==
null
)
{
OAuth2Error
error
=
new
OAuth2Error
(
OAuth2ErrorCodes
.
SERVER_ERROR
,
"The token generator failed to generate the access token."
,
ERROR_URI
);
throw
new
OAuth2AuthenticationException
(
error
);
}
OAuth2AccessToken
accessToken
=
new
OAuth2AccessToken
(
OAuth2AccessToken
.
TokenType
.
BEARER
,
generatedAccessToken
.
getTokenValue
(),
generatedAccessToken
.
getIssuedAt
(),
generatedAccessToken
.
getExpiresAt
(),
tokenContext
.
getAuthorizedScopes
());
// @formatter:off
OAuth2Authorization
.
Builder
authorizationBuilder
=
OAuth2Authorization
.
withRegisteredClient
(
registeredClient
)
.
principalName
(
usernamePasswordAuthentication
.
getName
())
.
authorizationGrantType
(
AuthorizationGrantType
.
PASSWORD
)
.
attribute
(
Principal
.
class
.
getName
(),
usernamePasswordAuthentication
);
// @formatter:on
if
(
generatedAccessToken
instanceof
ClaimAccessor
)
{
authorizationBuilder
.
token
(
accessToken
,
(
metadata
)
->
metadata
.
put
(
OAuth2Authorization
.
Token
.
CLAIMS_METADATA_NAME
,
((
ClaimAccessor
)
generatedAccessToken
).
getClaims
()));
}
else
{
authorizationBuilder
.
accessToken
(
accessToken
);
}
// ----- Refresh token -----
OAuth2RefreshToken
refreshToken
=
null
;
if
(
registeredClient
.
getAuthorizationGrantTypes
().
contains
(
AuthorizationGrantType
.
REFRESH_TOKEN
)
&&
// Do not issue refresh token to public client
!
clientPrincipal
.
getClientAuthenticationMethod
().
equals
(
ClientAuthenticationMethod
.
NONE
))
{
tokenContext
=
tokenContextBuilder
.
tokenType
(
OAuth2TokenType
.
REFRESH_TOKEN
).
build
();
OAuth2Token
generatedRefreshToken
=
this
.
tokenGenerator
.
generate
(
tokenContext
);
if
(!(
generatedRefreshToken
instanceof
OAuth2RefreshToken
))
{
OAuth2Error
error
=
new
OAuth2Error
(
OAuth2ErrorCodes
.
SERVER_ERROR
,
"The token generator failed to generate the refresh token."
,
ERROR_URI
);
throw
new
OAuth2AuthenticationException
(
error
);
}
refreshToken
=
(
OAuth2RefreshToken
)
generatedRefreshToken
;
authorizationBuilder
.
refreshToken
(
refreshToken
);
}
OAuth2Authorization
authorization
=
authorizationBuilder
.
build
();
this
.
authorizationService
.
save
(
authorization
);
return
new
OAuth2AccessTokenAuthenticationToken
(
registeredClient
,
clientPrincipal
,
accessToken
,
refreshToken
,
additionalParameters
);
}
@Override
public
boolean
supports
(
Class
<?>
authentication
)
{
return
ResourceOwnerPasswordAuthenticationToken
.
class
.
isAssignableFrom
(
authentication
);
}
private
static
OAuth2ClientAuthenticationToken
getAuthenticatedClientElseThrowInvalidClient
(
Authentication
authentication
)
{
OAuth2ClientAuthenticationToken
clientPrincipal
=
null
;
if
(
OAuth2ClientAuthenticationToken
.
class
.
isAssignableFrom
(
authentication
.
getPrincipal
().
getClass
()))
{
clientPrincipal
=
(
OAuth2ClientAuthenticationToken
)
authentication
.
getPrincipal
();
}
if
(
clientPrincipal
!=
null
&&
clientPrincipal
.
isAuthenticated
())
{
return
clientPrincipal
;
}
throw
new
OAuth2AuthenticationException
(
OAuth2ErrorCodes
.
INVALID_CLIENT
);
}
@Override
public
boolean
supports
(
Class
<?>
authentication
)
{
return
WechatAuthenticationToken
.
class
.
isAssignableFrom
(
authentication
);
}
}
youlai-auth/src/main/java/com/youlai/auth/authentication/wechat/WechatAuthenticationToken.java
浏览文件 @
84aa6da7
package
com.youlai.auth.authentication.wechat
;
import
jakarta.annotation.Nullable
;
import
lombok.Getter
;
import
org.springframework.security.authentication.AbstractAuthenticationToken
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.core.GrantedAuthority
;
import
org.springframework.security.oauth2.core.AuthorizationGrantType
;
import
org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames
;
import
org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationGrantAuthenticationToken
;
import
org.springframework.security.oauth2.server.authorization.util.SpringAuthorizationServerVersion
;
import
org.springframework.util.Assert
;
import
java.util.
Collection
;
import
java.util.
*
;
/**
* @author <a href="mailto:xianrui0365@163.com">haoxr</a>
* @since 2021/9/25
* 微信授权登录
*
* @author haoxr
* @since 3.0.0
*/
public
class
WechatAuthenticationToken
extends
AbstractAuthenticationToken
{
private
static
final
long
serialVersionUID
=
550L
;
private
final
Object
principal
;
@Getter
private
String
encryptedData
;
@Getter
private
String
iv
;
/**
* 账号校验之前的token构建
*
* @param principal
*/
public
WechatAuthenticationToken
(
Object
principal
,
String
encryptedData
,
String
iv
)
{
super
(
null
);
this
.
principal
=
principal
;
this
.
encryptedData
=
encryptedData
;
this
.
iv
=
iv
;
setAuthenticated
(
false
);
}
public
class
WechatAuthenticationToken
extends
OAuth2AuthorizationGrantAuthenticationToken
{
private
final
Set
<
String
>
scopes
;
/**
*
账号校验成功之后的token构建
*
{@link org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientCredentialsAuthenticationToken}
*
* @param
p
rincipal
* @param a
uthoritie
s
* @param
clientP
rincipal
* @param a
dditionalParameter
s
*/
public
WechatAuthenticationToken
(
Object
principal
,
Collection
<?
extends
GrantedAuthority
>
authorities
)
{
super
(
authorities
);
this
.
principal
=
principal
;
super
.
setAuthenticated
(
true
);
}
public
WechatAuthenticationToken
(
Authentication
clientPrincipal
,
@Nullable
Set
<
String
>
scopes
,
Map
<
String
,
Object
>
additionalParameters
)
{
super
(
AuthorizationGrantType
.
PASSWORD
,
clientPrincipal
,
additionalParameters
);
this
.
scopes
=
Collections
.
unmodifiableSet
(
scopes
!=
null
?
new
HashSet
<>(
scopes
)
:
Collections
.
emptySet
());
@Override
public
Object
getCredentials
()
{
return
null
;
}
@Override
public
Object
getPrincipal
()
{
return
this
.
principal
;
public
Set
<
String
>
getScopes
()
{
return
this
.
scopes
;
}
public
void
setAuthenticated
(
boolean
isAuthenticated
)
throws
IllegalArgumentException
{
Assert
.
isTrue
(!
isAuthenticated
,
"Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead"
);
super
.
setAuthenticated
(
false
);
@Override
public
Object
getCredentials
()
{
return
this
.
getAdditionalParameters
().
get
(
OAuth2ParameterNames
.
PASSWORD
);
}
public
void
eraseCredentials
()
{
super
.
eraseCredentials
();
}
}
youlai-auth/src/main/java/com/youlai/auth/authentication/wechat/WechatTokenGranter.java
已删除
100644 → 0
浏览文件 @
b019e6dd
package
com.youlai.auth.authentication.wechat
;
import
org.springframework.security.authentication.*
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.oauth2.common.exceptions.InvalidGrantException
;
import
org.springframework.security.oauth2.provider.*
;
import
org.springframework.security.oauth2.provider.token.AbstractTokenGranter
;
import
org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices
;
import
java.util.LinkedHashMap
;
import
java.util.Map
;
/**
* 微信授权者
*
* @author <a href="mailto:xianrui0365@163.com">haoxr</a>
* @since 2021/9/25
*/
public
class
WechatTokenGranter
extends
AbstractTokenGranter
{
/**
* 声明授权者 WechatTokenGranter 支持授权模式 wechat
* 根据接口传值 grant_type = wechat 的值匹配到此授权者
* 匹配逻辑详见下面的两个方法
*
* @see org.springframework.security.oauth2.provider.CompositeTokenGranter#grant(String, TokenRequest)
* @see org.springframework.security.oauth2.provider.token.AbstractTokenGranter#grant(String, TokenRequest)
*/
private
static
final
String
GRANT_TYPE
=
"wechat"
;
private
final
AuthenticationManager
authenticationManager
;
public
WechatTokenGranter
(
AuthorizationServerTokenServices
tokenServices
,
ClientDetailsService
clientDetailsService
,
OAuth2RequestFactory
requestFactory
,
AuthenticationManager
authenticationManager
)
{
super
(
tokenServices
,
clientDetailsService
,
requestFactory
,
GRANT_TYPE
);
this
.
authenticationManager
=
authenticationManager
;
}
@Override
protected
OAuth2Authentication
getOAuth2Authentication
(
ClientDetails
client
,
TokenRequest
tokenRequest
)
{
Map
<
String
,
String
>
parameters
=
new
LinkedHashMap
(
tokenRequest
.
getRequestParameters
());
String
code
=
parameters
.
get
(
"code"
);
String
encryptedData
=
parameters
.
get
(
"encryptedData"
);
String
iv
=
parameters
.
get
(
"iv"
);
// 移除后续无用参数
parameters
.
remove
(
"code"
);
parameters
.
remove
(
"encryptedData"
);
parameters
.
remove
(
"iv"
);
Authentication
userAuth
=
new
WechatAuthenticationToken
(
code
,
encryptedData
,
iv
);
// 未认证状态
((
AbstractAuthenticationToken
)
userAuth
).
setDetails
(
parameters
);
try
{
userAuth
=
this
.
authenticationManager
.
authenticate
(
userAuth
);
// 认证中
}
catch
(
Exception
e
)
{
throw
new
InvalidGrantException
(
e
.
getMessage
());
}
if
(
userAuth
!=
null
&&
userAuth
.
isAuthenticated
())
{
// 认证成功
OAuth2Request
storedOAuth2Request
=
this
.
getRequestFactory
().
createOAuth2Request
(
client
,
tokenRequest
);
return
new
OAuth2Authentication
(
storedOAuth2Request
,
userAuth
);
}
else
{
// 认证失败
throw
new
InvalidGrantException
(
"Could not authenticate code: "
+
code
);
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录