Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
MaxKey单点登录官方(MaxKeyTop)
MaxKey
提交
6cad9f0c
MaxKey
项目概览
MaxKey单点登录官方(MaxKeyTop)
/
MaxKey
9 个月 前同步成功
通知
75
Star
3
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
MaxKey
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
6cad9f0c
编写于
8月 12, 2021
作者:
M
MaxKey
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
oauth2 Approval fix & sso login history
上级
e0e299ff
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
122 addition
and
73 deletion
+122
-73
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/TokenApprovalStore.java
...ey/authz/oauth2/provider/approval/TokenApprovalStore.java
+19
-5
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/endpoint/OAuth20AccessConfirmationEndpoint.java
.../approval/endpoint/OAuth20AccessConfirmationEndpoint.java
+44
-40
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/token/store/RedisTokenStore.java
...ey/authz/oauth2/provider/token/store/RedisTokenStore.java
+57
-27
maxkey-webs/maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyMvcConfig.java
...-web-maxkey/src/main/java/org/maxkey/MaxKeyMvcConfig.java
+2
-1
未找到文件。
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/TokenApprovalStore.java
浏览文件 @
6cad9f0c
...
...
@@ -25,6 +25,8 @@ import org.maxkey.authz.oauth2.provider.OAuth2Authentication;
import
org.maxkey.authz.oauth2.provider.approval.Approval.ApprovalStatus
;
import
org.maxkey.authz.oauth2.provider.token.AuthorizationServerTokenServices
;
import
org.maxkey.authz.oauth2.provider.token.TokenStore
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
/**
* An {@link ApprovalStore} that works with an existing {@link TokenStore}, extracting implicit {@link Approval
...
...
@@ -38,6 +40,8 @@ import org.maxkey.authz.oauth2.provider.token.TokenStore;
*/
public
class
TokenApprovalStore
implements
ApprovalStore
{
static
final
Logger
_logger
=
LoggerFactory
.
getLogger
(
TokenApprovalStore
.
class
);
private
TokenStore
store
;
/**
...
...
@@ -55,6 +59,7 @@ public class TokenApprovalStore implements ApprovalStore {
*/
@Override
public
boolean
addApprovals
(
Collection
<
Approval
>
approvals
)
{
_logger
.
debug
(
"add Approvals..."
);
return
true
;
}
...
...
@@ -65,6 +70,7 @@ public class TokenApprovalStore implements ApprovalStore {
*/
@Override
public
boolean
revokeApprovals
(
Collection
<
Approval
>
approvals
)
{
_logger
.
debug
(
"revoke Approvals "
+
approvals
);
boolean
success
=
true
;
for
(
Approval
approval
:
approvals
)
{
Collection
<
OAuth2AccessToken
>
tokens
=
store
.
findTokensByClientIdAndUserName
(
approval
.
getClientId
(),
approval
.
getUserId
());
...
...
@@ -87,14 +93,22 @@ public class TokenApprovalStore implements ApprovalStore {
*/
@Override
public
Collection
<
Approval
>
getApprovals
(
String
userId
,
String
clientId
)
{
_logger
.
trace
(
"userId "
+
userId
+
" , clientId "
+
clientId
);
Collection
<
Approval
>
result
=
new
HashSet
<
Approval
>();
Collection
<
OAuth2AccessToken
>
tokens
=
store
.
findTokensByClientIdAndUserName
(
clientId
,
userId
);
_logger
.
trace
(
"tokens Collection "
+
tokens
);
for
(
OAuth2AccessToken
token
:
tokens
)
{
OAuth2Authentication
authentication
=
store
.
readAuthentication
(
token
);
if
(
authentication
!=
null
)
{
Date
expiresAt
=
token
.
getExpiration
();
for
(
String
scope
:
token
.
getScope
())
{
result
.
add
(
new
Approval
(
userId
,
clientId
,
scope
,
expiresAt
,
ApprovalStatus
.
APPROVED
));
_logger
.
trace
(
"token "
+
token
);
if
(
token
!=
null
)
{
OAuth2Authentication
authentication
=
store
.
readAuthentication
(
token
);
_logger
.
trace
(
"authentication "
+
authentication
);
if
(
authentication
!=
null
)
{
Date
expiresAt
=
token
.
getExpiration
();
for
(
String
scope
:
token
.
getScope
())
{
Approval
approval
=
new
Approval
(
userId
,
clientId
,
scope
,
expiresAt
,
ApprovalStatus
.
APPROVED
);
result
.
add
(
approval
);
_logger
.
trace
(
"add approval "
+
approval
);
}
}
}
}
...
...
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/endpoint/OAuth20AccessConfirmationEndpoint.java
浏览文件 @
6cad9f0c
...
...
@@ -77,48 +77,52 @@ public class OAuth20AccessConfirmationEndpoint {
*/
@RequestMapping
(
OAuth2Constants
.
ENDPOINT
.
ENDPOINT_APPROVAL_CONFIRM
)
public
ModelAndView
getAccessConfirmation
(
@RequestParam
Map
<
String
,
Object
>
model
)
throws
Exception
{
model
.
remove
(
"authorizationRequest"
);
// Map<String, Object> model
AuthorizationRequest
clientAuth
=
(
AuthorizationRequest
)
WebContext
.
getAttribute
(
"authorizationRequest"
);
ClientDetails
client
=
clientDetailsService
.
loadClientByClientId
(
clientAuth
.
getClientId
());
Apps
app
=
(
Apps
)
WebContext
.
getAttribute
(
WebConstants
.
AUTHORIZE_SIGN_ON_APP
);
//session中为空或者id不一致重新加载
if
(
app
==
null
||
!
app
.
getId
().
equalsIgnoreCase
(
clientAuth
.
getClientId
()))
{
app
=
appsService
.
get
(
clientAuth
.
getClientId
());
WebContext
.
setAttribute
(
WebConstants
.
AUTHORIZE_SIGN_ON_APP
,
app
);
WebContext
.
setAttribute
(
app
.
getId
(),
app
.
getIcon
());
}
model
.
put
(
"auth_request"
,
clientAuth
);
model
.
put
(
"client"
,
client
);
model
.
put
(
"app"
,
app
);
model
.
put
(
"oauth_version"
,
"oauth 2.0"
);
Map
<
String
,
String
>
scopes
=
new
LinkedHashMap
<
String
,
String
>();
for
(
String
scope
:
clientAuth
.
getScope
())
{
scopes
.
put
(
OAuth2Utils
.
SCOPE_PREFIX
+
scope
,
"false"
);
}
String
principal
=
((
SigninPrincipal
)
WebContext
.
getAuthentication
().
getPrincipal
()).
getUsername
();
for
(
Approval
approval
:
approvalStore
.
getApprovals
(
principal
,
client
.
getClientId
()))
{
if
(
clientAuth
.
getScope
().
contains
(
approval
.
getScope
()))
{
scopes
.
put
(
OAuth2Utils
.
SCOPE_PREFIX
+
approval
.
getScope
(),
approval
.
getStatus
()
==
ApprovalStatus
.
APPROVED
?
"true"
:
"false"
);
}
}
model
.
put
(
"scopes"
,
scopes
);
if
(!
model
.
containsKey
(
OAuth2Constants
.
PARAMETER
.
APPROVAL_PROMPT
))
{
model
.
put
(
OAuth2Constants
.
PARAMETER
.
APPROVAL_PROMPT
,
client
.
getApprovalPrompt
());
}
@RequestParam
Map
<
String
,
Object
>
model
)
{
try
{
model
.
remove
(
"authorizationRequest"
);
// Map<String, Object> model
AuthorizationRequest
clientAuth
=
(
AuthorizationRequest
)
WebContext
.
getAttribute
(
"authorizationRequest"
);
ClientDetails
client
=
clientDetailsService
.
loadClientByClientId
(
clientAuth
.
getClientId
());
Apps
app
=
(
Apps
)
WebContext
.
getAttribute
(
WebConstants
.
AUTHORIZE_SIGN_ON_APP
);
//session中为空或者id不一致重新加载
if
(
app
==
null
||
!
app
.
getId
().
equalsIgnoreCase
(
clientAuth
.
getClientId
()))
{
app
=
appsService
.
get
(
clientAuth
.
getClientId
());
WebContext
.
setAttribute
(
WebConstants
.
AUTHORIZE_SIGN_ON_APP
,
app
);
WebContext
.
setAttribute
(
app
.
getId
(),
app
.
getIcon
());
}
model
.
put
(
"auth_request"
,
clientAuth
);
model
.
put
(
"client"
,
client
);
model
.
put
(
"app"
,
app
);
model
.
put
(
"oauth_version"
,
"oauth 2.0"
);
Map
<
String
,
String
>
scopes
=
new
LinkedHashMap
<
String
,
String
>();
for
(
String
scope
:
clientAuth
.
getScope
())
{
scopes
.
put
(
OAuth2Utils
.
SCOPE_PREFIX
+
scope
,
"false"
);
}
String
principal
=
((
SigninPrincipal
)
WebContext
.
getAuthentication
().
getPrincipal
()).
getUsername
();
for
(
Approval
approval
:
approvalStore
.
getApprovals
(
principal
,
client
.
getClientId
()))
{
if
(
clientAuth
.
getScope
().
contains
(
approval
.
getScope
()))
{
scopes
.
put
(
OAuth2Utils
.
SCOPE_PREFIX
+
approval
.
getScope
(),
approval
.
getStatus
()
==
ApprovalStatus
.
APPROVED
?
"true"
:
"false"
);
}
}
model
.
put
(
"scopes"
,
scopes
);
if
(!
model
.
containsKey
(
OAuth2Constants
.
PARAMETER
.
APPROVAL_PROMPT
))
{
model
.
put
(
OAuth2Constants
.
PARAMETER
.
APPROVAL_PROMPT
,
client
.
getApprovalPrompt
());
}
}
catch
(
Exception
e
)
{
_logger
.
debug
(
"OAuth Access Confirmation process error."
,
e
);
}
ModelAndView
modelAndView
=
new
ModelAndView
(
"authorize/oauth_access_confirmation"
);
_logger
.
debug
(
"Confirmation details "
);
_logger
.
trace
(
"Confirmation details "
);
for
(
Object
key
:
model
.
keySet
())
{
_logger
.
debug
(
"key "
+
key
+
"="
+
model
.
get
(
key
));
_logger
.
trace
(
"key "
+
key
+
"="
+
model
.
get
(
key
));
}
modelAndView
.
addObject
(
"model"
,
model
);
return
modelAndView
;
...
...
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/token/store/RedisTokenStore.java
浏览文件 @
6cad9f0c
...
...
@@ -32,6 +32,8 @@ import org.maxkey.authz.oauth2.provider.token.TokenStore;
import
org.maxkey.persistence.redis.RedisConnection
;
import
org.maxkey.persistence.redis.RedisConnectionFactory
;
import
org.maxkey.util.ObjectTransformer
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.util.Date
;
...
...
@@ -39,16 +41,17 @@ import java.util.Date;
* @author efenderbosch
*/
public
class
RedisTokenStore
implements
TokenStore
{
private
static
final
String
ACCESS
=
"REDIS_OAUTH_V20_access:"
;
private
static
final
String
AUTH_TO_ACCESS
=
"REDIS_OAUTH_V20_auth_to_access:"
;
private
static
final
String
AUTH
=
"REDIS_OAUTH_V20_auth:"
;
private
static
final
String
REFRESH_AUTH
=
"REDIS_OAUTH_V20_refresh_auth:"
;
private
static
final
String
ACCESS_TO_REFRESH
=
"REDIS_OAUTH_V20_access_to_refresh:"
;
private
static
final
String
REFRESH
=
"REDIS_OAUTH_V20_refresh:"
;
private
static
final
String
REFRESH_TO_ACCESS
=
"REDIS_OAUTH_V20_refresh_to_access:"
;
private
static
final
String
CLIENT_ID_TO_ACCESS
=
"REDIS_OAUTH_V20_client_id_to_access:"
;
private
static
final
String
UNAME_TO_ACCESS
=
"REDIS_OAUTH_V20_uname_to_access:"
;
static
final
Logger
_logger
=
LoggerFactory
.
getLogger
(
RedisTokenStore
.
class
);
private
static
final
String
ACCESS
=
"REDIS_OAUTH_V20_ACCESS_"
;
private
static
final
String
AUTH_TO_ACCESS
=
"REDIS_OAUTH_V20_AUTH_TO_ACCESS_"
;
private
static
final
String
AUTH
=
"REDIS_OAUTH_V20_AUTH_"
;
private
static
final
String
REFRESH_AUTH
=
"REDIS_OAUTH_V20_REFRESH_AUTH_"
;
private
static
final
String
ACCESS_TO_REFRESH
=
"REDIS_OAUTH_V20_ACCESS_TO_REFRESH_"
;
private
static
final
String
REFRESH
=
"REDIS_OAUTH_V20_REFRESH_"
;
private
static
final
String
REFRESH_TO_ACCESS
=
"REDIS_OAUTH_V20_REFRESH_TO_ACCESS_"
;
private
static
final
String
CLIENT_ID_TO_ACCESS
=
"REDIS_OAUTH_V20_CLIENT_ID_TO_ACCESS_"
;
private
static
final
String
UNAME_TO_ACCESS
=
"REDIS_OAUTH_V20_UNAME_TO_ACCESS_"
;
private
final
RedisConnectionFactory
connectionFactory
;
private
AuthenticationKeyGenerator
authenticationKeyGenerator
=
new
DefaultAuthenticationKeyGenerator
();
...
...
@@ -77,15 +80,19 @@ public class RedisTokenStore implements TokenStore {
String
key
=
authenticationKeyGenerator
.
extractKey
(
authentication
);
String
serializedKey
=
(
AUTH_TO_ACCESS
+
key
);
RedisConnection
conn
=
getConnection
();
OAuth2AccessToken
accessToken
=
conn
.
getObject
(
serializedKey
);
if
(
accessToken
!=
null
&&
!
key
.
equals
(
authenticationKeyGenerator
.
extractKey
(
readAuthentication
(
accessToken
.
getValue
()))))
{
// Keep the stores consistent (maybe the same user is
// represented by this authentication but the details have
// changed)
storeAccessToken
(
accessToken
,
authentication
);
try
{
OAuth2AccessToken
accessToken
=
conn
.
getObject
(
serializedKey
);
if
(
accessToken
!=
null
&&
!
key
.
equals
(
authenticationKeyGenerator
.
extractKey
(
readAuthentication
(
accessToken
.
getValue
()))))
{
// Keep the stores consistent (maybe the same user is
// represented by this authentication but the details have
// changed)
storeAccessToken
(
accessToken
,
authentication
);
}
return
accessToken
;
}
finally
{
conn
.
close
();
}
return
accessToken
;
}
@Override
...
...
@@ -95,9 +102,14 @@ public class RedisTokenStore implements TokenStore {
@Override
public
OAuth2Authentication
readAuthentication
(
String
token
)
{
_logger
.
trace
(
"read Authentication by token "
+
token
+
" , token key "
+
AUTH
+
token
);
RedisConnection
conn
=
getConnection
();
OAuth2Authentication
auth
=
conn
.
getObject
(
AUTH
+
token
);
return
auth
;
try
{
OAuth2Authentication
auth
=
conn
.
getObject
(
AUTH
+
token
);
return
auth
;
}
finally
{
conn
.
close
();
}
}
@Override
...
...
@@ -122,6 +134,11 @@ public class RedisTokenStore implements TokenStore {
String
authToAccessKey
=
(
AUTH_TO_ACCESS
+
authenticationKeyGenerator
.
extractKey
(
authentication
));
String
approvalKey
=
(
UNAME_TO_ACCESS
+
getApprovalKey
(
authentication
));
String
clientId
=
(
CLIENT_ID_TO_ACCESS
+
authentication
.
getOAuth2Request
().
getClientId
());
_logger
.
trace
(
"accessKey "
+
accessKey
);
_logger
.
trace
(
"authKey "
+
authKey
);
_logger
.
trace
(
"authToAccessKey "
+
authToAccessKey
);
_logger
.
trace
(
"approvalKey "
+
approvalKey
);
_logger
.
trace
(
"clientId "
+
clientId
);
RedisConnection
conn
=
getConnection
();
try
{
...
...
@@ -146,8 +163,10 @@ public class RedisTokenStore implements TokenStore {
String
refresh
=
(
token
.
getRefreshToken
().
getValue
());
String
auth
=
(
token
.
getValue
());
String
refreshToAccessKey
=
(
REFRESH_TO_ACCESS
+
token
.
getRefreshToken
().
getValue
());
_logger
.
trace
(
"refreshToAccessKey "
+
refreshToAccessKey
);
conn
.
set
(
refreshToAccessKey
,
auth
);
String
accessToRefreshKey
=
(
ACCESS_TO_REFRESH
+
token
.
getValue
());
_logger
.
trace
(
"accessToRefreshKey "
+
accessToRefreshKey
);
conn
.
set
(
accessToRefreshKey
,
refresh
);
if
(
refreshToken
instanceof
ExpiringOAuth2RefreshToken
)
{
ExpiringOAuth2RefreshToken
expiringRefreshToken
=
(
ExpiringOAuth2RefreshToken
)
refreshToken
;
...
...
@@ -173,7 +192,7 @@ public class RedisTokenStore implements TokenStore {
}
private
static
String
getApprovalKey
(
String
clientId
,
String
userName
)
{
return
clientId
+
(
userName
==
null
?
""
:
"
:
"
+
userName
);
return
clientId
+
(
userName
==
null
?
""
:
"
_
"
+
userName
);
}
@Override
...
...
@@ -184,9 +203,13 @@ public class RedisTokenStore implements TokenStore {
@Override
public
OAuth2AccessToken
readAccessToken
(
String
tokenValue
)
{
RedisConnection
conn
=
getConnection
();
String
key
=
(
ACCESS
+
tokenValue
);
OAuth2AccessToken
accessToken
=
conn
.
getObject
(
key
);
return
accessToken
;
try
{
String
key
=
(
ACCESS
+
tokenValue
);
OAuth2AccessToken
accessToken
=
conn
.
getObject
(
key
);
return
accessToken
;
}
finally
{
conn
.
close
();
}
}
public
void
removeAccessToken
(
String
tokenValue
)
{
...
...
@@ -251,9 +274,13 @@ public class RedisTokenStore implements TokenStore {
public
OAuth2RefreshToken
readRefreshToken
(
String
tokenValue
)
{
String
key
=
(
REFRESH
+
tokenValue
);
RedisConnection
conn
=
getConnection
();
OAuth2RefreshToken
refreshToken
=
conn
.
getObject
(
key
);
conn
.
close
();
return
refreshToken
;
try
{
OAuth2RefreshToken
refreshToken
=
conn
.
getObject
(
key
);
conn
.
close
();
return
refreshToken
;
}
finally
{
conn
.
close
();
}
}
@Override
...
...
@@ -309,6 +336,7 @@ public class RedisTokenStore implements TokenStore {
@Override
public
Collection
<
OAuth2AccessToken
>
findTokensByClientIdAndUserName
(
String
clientId
,
String
userName
)
{
String
approvalKey
=
(
UNAME_TO_ACCESS
+
getApprovalKey
(
clientId
,
userName
));
_logger
.
trace
(
"approvalKey "
+
approvalKey
);
List
<
String
>
stringList
=
null
;
RedisConnection
conn
=
getConnection
();
try
{
...
...
@@ -321,6 +349,7 @@ public class RedisTokenStore implements TokenStore {
}
List
<
OAuth2AccessToken
>
accessTokens
=
new
ArrayList
<
OAuth2AccessToken
>(
stringList
.
size
());
for
(
String
str
:
stringList
)
{
//accessToken may expired
OAuth2AccessToken
accessToken
=
conn
.
getObject
(
str
);
accessTokens
.
add
(
accessToken
);
}
...
...
@@ -330,6 +359,7 @@ public class RedisTokenStore implements TokenStore {
@Override
public
Collection
<
OAuth2AccessToken
>
findTokensByClientId
(
String
clientId
)
{
String
key
=
(
CLIENT_ID_TO_ACCESS
+
clientId
);
_logger
.
trace
(
"TokensByClientId "
+
key
);
List
<
String
>
stringList
=
null
;
RedisConnection
conn
=
getConnection
();
try
{
...
...
maxkey-webs/maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyMvcConfig.java
浏览文件 @
6cad9f0c
...
...
@@ -211,12 +211,13 @@ public class MaxKeyMvcConfig implements WebMvcConfigurer {
registry
.
addInterceptor
(
historyLoginAppAdapter
)
.
addPathPatterns
(
"/authz/basic/*"
)
.
addPathPatterns
(
"/authz/ltpa/*"
)
.
addPathPatterns
(
"/authz/
desktop
/*"
)
.
addPathPatterns
(
"/authz/
api
/*"
)
.
addPathPatterns
(
"/authz/formbased/*"
)
.
addPathPatterns
(
"/authz/tokenbased/*"
)
.
addPathPatterns
(
"/authz/saml20/idpinit/*"
)
.
addPathPatterns
(
"/authz/saml20/assertion"
)
.
addPathPatterns
(
"/authz/cas/granting"
)
.
addPathPatterns
(
"/authz/oauth/v20/approval_confirm"
)
;
_logger
.
debug
(
"add HistoryLoginAppAdapter"
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录