Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
MaxKey单点登录官方(MaxKeyTop)
MaxKey
提交
173f7792
MaxKey
项目概览
MaxKey单点登录官方(MaxKeyTop)
/
MaxKey
10 个月 前同步成功
通知
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 搜索 >>
提交
173f7792
编写于
4月 09, 2021
作者:
M
MaxKey
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
/authz/oauth/v20
上级
0325f76e
变更
18
隐藏空白更改
内联
并排
Showing
18 changed file
with
418 addition
and
213 deletion
+418
-213
maxkey-persistence/src/test/resources/application.properties
maxkey-persistence/src/test/resources/application.properties
+2
-2
maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/endpoint/AuthorizeEndpoint.java
...ain/java/org/maxkey/authz/endpoint/AuthorizeEndpoint.java
+1
-1
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/common/OAuth2Constants.java
.../java/org/maxkey/authz/oauth2/common/OAuth2Constants.java
+76
-0
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/controller/OAuth20AccessConfirmationController.java
...roval/controller/OAuth20AccessConfirmationController.java
+3
-2
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/AuthorizationEndpoint.java
...authz/oauth2/provider/endpoint/AuthorizationEndpoint.java
+7
-6
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/CheckTokenEndpoint.java
...ey/authz/oauth2/provider/endpoint/CheckTokenEndpoint.java
+2
-1
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpoint.java
.../maxkey/authz/oauth2/provider/endpoint/TokenEndpoint.java
+3
-2
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpointAuthenticationFilter.java
.../provider/endpoint/TokenEndpointAuthenticationFilter.java
+2
-1
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenKeyEndpoint.java
...xkey/authz/oauth2/provider/endpoint/TokenKeyEndpoint.java
+2
-1
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/OpenIdConnectUserInfoEndpoint.java
...ider/userinfo/endpoint/OpenIdConnectUserInfoEndpoint.java
+302
-0
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/UserInfoEndpoint.java
...z/oauth2/provider/userinfo/endpoint/UserInfoEndpoint.java
+2
-182
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/autoconfigure/Oauth20AutoConfiguration.java
...va/org/maxkey/autoconfigure/Oauth20AutoConfiguration.java
+2
-1
maxkey-web-manage/src/main/resources/application.properties
maxkey-web-manage/src/main/resources/application.properties
+2
-2
maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyMvcConfig.java
...-web-maxkey/src/main/java/org/maxkey/MaxKeyMvcConfig.java
+2
-2
maxkey-web-maxkey/src/main/resources/application-http.properties
...web-maxkey/src/main/resources/application-http.properties
+2
-2
maxkey-web-maxkey/src/main/resources/application-https.properties
...eb-maxkey/src/main/resources/application-https.properties
+2
-2
maxkey-web-maxkey/src/main/resources/static/trusts/openid-configuration
...key/src/main/resources/static/trusts/openid-configuration
+5
-5
maxkey-web-maxkey/src/main/resources/templates/views/authorize/oauth_access_confirmation.ftl
...s/templates/views/authorize/oauth_access_confirmation.ftl
+1
-1
未找到文件。
maxkey-persistence/src/test/resources/application.properties
浏览文件 @
173f7792
...
...
@@ -207,8 +207,8 @@ maxkey.support.wsfederation.logoutUrl=https://adfs.maxkey.top/adfs/ls/?wa=wsigno
#############################################################################
# OIDC V1.0 METADATA configuration
maxkey.oidc.metadata.issuer
=
${maxkey.server.name}/maxkey
maxkey.oidc.metadata.authorizationEndpoint
=
${maxkey.server.name}/maxkey/oauth/v20/authorize
maxkey.oidc.metadata.tokenEndpoint
=
${maxkey.server.name}/maxkey/oauth/v20/token
maxkey.oidc.metadata.authorizationEndpoint
=
${maxkey.server.name}/maxkey/
authz/
oauth/v20/authorize
maxkey.oidc.metadata.tokenEndpoint
=
${maxkey.server.name}/maxkey/
authz/
oauth/v20/token
maxkey.oidc.metadata.userinfoEndpoint
=
${maxkey.server.name}/maxkey/api/connect/userinfo
#############################################################################
...
...
maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/endpoint/AuthorizeEndpoint.java
浏览文件 @
173f7792
...
...
@@ -64,7 +64,7 @@ public class AuthorizeEndpoint extends AuthorizeBaseEndpoint{
}
else
if
(
application
.
getProtocol
().
equalsIgnoreCase
(
ConstantsProtocols
.
FORMBASED
)){
modelAndView
=
WebContext
.
forward
(
"/authz/formbased/"
+
id
);
}
else
if
(
application
.
getProtocol
().
equalsIgnoreCase
(
ConstantsProtocols
.
OAUTH20
)){
modelAndView
=
WebContext
.
forward
(
"/authz/oauthv20/"
+
application
.
getId
());
modelAndView
=
WebContext
.
forward
(
"/authz/oauth
/
v20/"
+
application
.
getId
());
}
else
if
(
application
.
getProtocol
().
equalsIgnoreCase
(
ConstantsProtocols
.
OPEN_ID_CONNECT
)){
// modelAndView=new ModelAndView("openid connect");
}
else
if
(
application
.
getProtocol
().
equalsIgnoreCase
(
ConstantsProtocols
.
SAML20
)){
...
...
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/common/OAuth2Constants.java
0 → 100644
浏览文件 @
173f7792
package
org.maxkey.authz.oauth2.common
;
public
class
OAuth2Constants
{
public
static
final
class
PARAMETER
{
/**
* Constant to use while parsing and formatting parameter maps for OAuth2 requests
*/
public
static
final
String
CLIENT_ID
=
"client_id"
;
public
static
final
String
CLIENT_SECRET
=
"client_secret"
;
/**
* Constant to use while parsing and formatting parameter maps for OAuth2 requests
*/
public
static
final
String
STATE
=
"state"
;
/**
* Constant to use while parsing and formatting parameter maps for OAuth2 requests
*/
public
static
final
String
SCOPE
=
"scope"
;
public
static
final
String
CODE
=
"code"
;
public
static
final
String
EXPIRES_IN
=
"expires_in"
;
/**
* Constant to use while parsing and formatting parameter maps for OAuth2 requests
*/
public
static
final
String
REDIRECT_URI
=
"redirect_uri"
;
/**
* Constant to use while parsing and formatting parameter maps for OAuth2 requests
*/
public
static
final
String
RESPONSE_TYPE
=
"response_type"
;
/**
* Constant to use while parsing and formatting parameter maps for OAuth2 requests
*/
public
static
final
String
USER_OAUTH_APPROVAL
=
"user_oauth_approval"
;
/**
* Constant to use as a prefix for scope approval
*/
public
static
final
String
SCOPE_PREFIX
=
"scope."
;
/**
* Constant to use while parsing and formatting parameter maps for OAuth2 requests
*/
public
static
final
String
GRANT_TYPE
=
"grant_type"
;
public
static
final
String
ACCESS_TOKEN
=
"access_token"
;
}
public
static
class
ENDPOINT
{
public
final
static
String
ENDPOINT_BASE
=
"/authz/oauth/v20"
;
public
final
static
String
ENDPOINT_AUTHORIZE
=
ENDPOINT_BASE
+
"/authorize"
;
public
final
static
String
ENDPOINT_TOKEN
=
ENDPOINT_BASE
+
"/token"
;
public
final
static
String
ENDPOINT_CHECK_TOKEN
=
ENDPOINT_BASE
+
"/check_token"
;
public
final
static
String
ENDPOINT_TOKEN_KEY
=
ENDPOINT_BASE
+
"/token_key"
;
public
final
static
String
ENDPOINT_APPROVAL_CONFIRM
=
ENDPOINT_BASE
+
"/approval_confirm"
;
public
final
static
String
ENDPOINT_ERROR
=
ENDPOINT_BASE
+
"/error"
;
public
final
static
String
ENDPOINT_USERINFO
=
"/api/oauth/v20/me"
;
public
final
static
String
ENDPOINT_OPENID_CONNECT_USERINFO
=
"/api/connect/v10/userinfo"
;
}
}
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/controller/OAuth20AccessConfirmationController.java
浏览文件 @
173f7792
...
...
@@ -22,6 +22,7 @@ import java.util.LinkedHashMap;
import
java.util.Map
;
import
org.maxkey.authn.SigninPrincipal
;
import
org.maxkey.authz.endpoint.AuthorizeBaseEndpoint
;
import
org.maxkey.authz.oauth2.common.OAuth2Constants
;
import
org.maxkey.authz.oauth2.common.util.OAuth2Utils
;
import
org.maxkey.authz.oauth2.provider.AuthorizationRequest
;
import
org.maxkey.authz.oauth2.provider.ClientDetailsService
;
...
...
@@ -73,7 +74,7 @@ public class OAuth20AccessConfirmationController {
* @return
* throws Exception
*/
@RequestMapping
(
"/oauth/v20/approval_confirm"
)
@RequestMapping
(
OAuth2Constants
.
ENDPOINT
.
ENDPOINT_APPROVAL_CONFIRM
)
public
ModelAndView
getAccessConfirmation
(
@RequestParam
Map
<
String
,
Object
>
model
)
throws
Exception
{
model
.
remove
(
"authorizationRequest"
);
...
...
@@ -123,7 +124,7 @@ public class OAuth20AccessConfirmationController {
* @return
* throws Exception
*/
@RequestMapping
(
"/oauth/v20/error"
)
@RequestMapping
(
OAuth2Constants
.
ENDPOINT
.
ENDPOINT_ERROR
)
public
String
handleError
(
Map
<
String
,
Object
>
model
)
throws
Exception
{
// We can add more stuff to the model here for JSP rendering. If the client was
// a machine then
...
...
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/AuthorizationEndpoint.java
浏览文件 @
173f7792
...
...
@@ -25,6 +25,7 @@ import javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse
;
import
org.maxkey.authz.oauth2.common.OAuth2AccessToken
;
import
org.maxkey.authz.oauth2.common.OAuth2Constants
;
import
org.maxkey.authz.oauth2.common.exceptions.InvalidClientException
;
import
org.maxkey.authz.oauth2.common.exceptions.InvalidRequestException
;
import
org.maxkey.authz.oauth2.common.exceptions.OAuth2Exception
;
...
...
@@ -99,7 +100,7 @@ import org.maxkey.authz.oauth2.provider.ClientDetailsService;
public
class
AuthorizationEndpoint
extends
AbstractEndpoint
{
final
static
Logger
_logger
=
LoggerFactory
.
getLogger
(
AuthorizationEndpoint
.
class
);
private
static
final
String
OAUTH_V20_AUTHORIZATION_URL
=
"%s
/oauth/v20/authorize
?client_id=%s&response_type=code&redirect_uri=%s&approval_prompt=auto"
;
private
static
final
String
OAUTH_V20_AUTHORIZATION_URL
=
"%s
"
+
OAuth2Constants
.
ENDPOINT
.
ENDPOINT_AUTHORIZE
+
"
?client_id=%s&response_type=code&redirect_uri=%s&approval_prompt=auto"
;
@Autowired
@Qualifier
(
"oauth20JdbcClientDetailsService"
)
...
...
@@ -117,9 +118,9 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
private
OAuth2RequestValidator
oauth2RequestValidator
=
new
DefaultOAuth2RequestValidator
();
private
String
userApprovalPage
=
"forward:
/oauth/v20/approval_confirm"
;
private
String
userApprovalPage
=
"forward:
"
+
OAuth2Constants
.
ENDPOINT
.
ENDPOINT_APPROVAL_CONFIRM
;
private
String
errorPage
=
"forward:
/oauth/error"
;
private
String
errorPage
=
"forward:
"
+
OAuth2Constants
.
ENDPOINT
.
ENDPOINT_ERROR
;
private
Object
implicitLock
=
new
Object
();
...
...
@@ -132,7 +133,7 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
}
@ApiOperation
(
value
=
"OAuth 2.0 认证接口"
,
notes
=
"传递参数client_id,response_type,redirect_uri等"
,
httpMethod
=
"GET"
)
@RequestMapping
(
value
=
"/oauth/v20/authorize"
,
method
=
RequestMethod
.
GET
)
@RequestMapping
(
value
=
OAuth2Constants
.
ENDPOINT
.
ENDPOINT_AUTHORIZE
,
method
=
RequestMethod
.
GET
)
public
ModelAndView
authorize
(
Map
<
String
,
Object
>
model
,
@RequestParam
Map
<
String
,
String
>
parameters
,
SessionStatus
sessionStatus
)
{
Principal
principal
=(
Principal
)
WebContext
.
getAuthentication
();
...
...
@@ -211,7 +212,7 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
}
@RequestMapping
(
value
=
"/oauth/v20/authorize"
,
method
=
RequestMethod
.
POST
,
params
=
OAuth2Utils
.
USER_OAUTH_APPROVAL
)
@RequestMapping
(
value
=
OAuth2Constants
.
ENDPOINT
.
ENDPOINT_AUTHORIZE
,
method
=
RequestMethod
.
POST
,
params
=
OAuth2Utils
.
USER_OAUTH_APPROVAL
)
public
View
approveOrDeny
(
@RequestParam
Map
<
String
,
String
>
approvalParameters
,
Map
<
String
,
?>
model
,
SessionStatus
sessionStatus
)
{
Principal
principal
=(
Principal
)
WebContext
.
getAuthentication
();
...
...
@@ -514,7 +515,7 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
}
@ApiOperation
(
value
=
"OAuth 2.0 认证接口"
,
notes
=
"传递参数应用ID,自动完成跳转认证拼接"
,
httpMethod
=
"GET"
)
@RequestMapping
(
"/authz/oauthv20
/{id}"
)
@RequestMapping
(
OAuth2Constants
.
ENDPOINT
.
ENDPOINT_BASE
+
"
/{id}"
)
public
ModelAndView
authorize
(
HttpServletRequest
request
,
HttpServletResponse
response
,
...
...
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/CheckTokenEndpoint.java
浏览文件 @
173f7792
...
...
@@ -34,6 +34,7 @@ import java.util.Map;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.LogFactory
;
import
org.maxkey.authz.oauth2.common.OAuth2AccessToken
;
import
org.maxkey.authz.oauth2.common.OAuth2Constants
;
import
org.maxkey.authz.oauth2.common.exceptions.InvalidTokenException
;
import
org.maxkey.authz.oauth2.common.exceptions.OAuth2Exception
;
import
org.maxkey.authz.oauth2.provider.OAuth2Authentication
;
...
...
@@ -81,7 +82,7 @@ public class CheckTokenEndpoint {
}
@ApiOperation
(
value
=
"OAuth 2.0 token检查接口"
,
notes
=
"传递参数token"
,
httpMethod
=
"POST"
)
@RequestMapping
(
value
=
"/oauth/v20/check_token"
)
@RequestMapping
(
value
=
OAuth2Constants
.
ENDPOINT
.
ENDPOINT_CHECK_TOKEN
)
@ResponseBody
public
Map
<
String
,
?>
checkToken
(
@RequestParam
(
"token"
)
String
value
)
{
...
...
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpoint.java
浏览文件 @
173f7792
...
...
@@ -25,6 +25,7 @@ import java.util.Set;
import
org.maxkey.authn.SigninPrincipal
;
import
org.maxkey.authz.oauth2.common.DefaultOAuth2AccessToken
;
import
org.maxkey.authz.oauth2.common.OAuth2AccessToken
;
import
org.maxkey.authz.oauth2.common.OAuth2Constants
;
import
org.maxkey.authz.oauth2.common.exceptions.InvalidClientException
;
import
org.maxkey.authz.oauth2.common.exceptions.InvalidGrantException
;
import
org.maxkey.authz.oauth2.common.exceptions.InvalidRequestException
;
...
...
@@ -89,7 +90,7 @@ public class TokenEndpoint extends AbstractEndpoint {
* @throws HttpRequestMethodNotSupportedException
*/
@ApiOperation
(
value
=
"OAuth 2.0 获取AccessToken接口"
,
notes
=
"传递参数token等"
,
httpMethod
=
"GET"
)
@RequestMapping
(
value
=
"/oauth/v20/token"
,
method
=
RequestMethod
.
GET
)
@RequestMapping
(
value
=
OAuth2Constants
.
ENDPOINT
.
ENDPOINT_TOKEN
,
method
=
RequestMethod
.
GET
)
public
ResponseEntity
<
OAuth2AccessToken
>
getAccessToken
(
@RequestParam
Map
<
String
,
String
>
parameters
)
throws
HttpRequestMethodNotSupportedException
{
if
(!
allowedRequestMethods
.
contains
(
HttpMethod
.
GET
))
{
...
...
@@ -99,7 +100,7 @@ public class TokenEndpoint extends AbstractEndpoint {
}
@ApiOperation
(
value
=
"OAuth 2.0 获取AccessToken接口"
,
notes
=
"传递参数token等"
,
httpMethod
=
"POST"
)
@RequestMapping
(
value
=
"/oauth/v20/token"
,
method
=
RequestMethod
.
POST
)
@RequestMapping
(
value
=
OAuth2Constants
.
ENDPOINT
.
ENDPOINT_TOKEN
,
method
=
RequestMethod
.
POST
)
public
ResponseEntity
<
OAuth2AccessToken
>
postAccessToken
(
@RequestParam
Map
<
String
,
String
>
parameters
)
throws
HttpRequestMethodNotSupportedException
{
// TokenEndpointAuthenticationFilter
...
...
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpointAuthenticationFilter.java
浏览文件 @
173f7792
...
...
@@ -35,6 +35,7 @@ import javax.servlet.http.HttpServletResponse;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.LogFactory
;
import
org.maxkey.authn.SigninPrincipal
;
import
org.maxkey.authz.oauth2.common.OAuth2Constants
;
import
org.maxkey.authz.oauth2.common.util.OAuth2Utils
;
import
org.maxkey.authz.oauth2.provider.AuthorizationRequest
;
import
org.maxkey.authz.oauth2.provider.OAuth2Authentication
;
...
...
@@ -77,7 +78,7 @@ import org.springframework.web.HttpRequestMethodNotSupportedException;
* @author Dave Syer
*
*/
@WebFilter
(
filterName
=
"TokenEndpointAuthenticationFilter"
,
urlPatterns
=
"/oauth/v20/token
/*"
)
@WebFilter
(
filterName
=
"TokenEndpointAuthenticationFilter"
,
urlPatterns
=
OAuth2Constants
.
ENDPOINT
.
ENDPOINT_TOKEN
+
"
/*"
)
public
class
TokenEndpointAuthenticationFilter
implements
Filter
{
private
static
final
Log
logger
=
LogFactory
.
getLog
(
TokenEndpointAuthenticationFilter
.
class
);
...
...
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenKeyEndpoint.java
浏览文件 @
173f7792
...
...
@@ -34,6 +34,7 @@ import java.util.Map;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.LogFactory
;
import
org.maxkey.authz.oauth2.common.OAuth2Constants
;
import
org.maxkey.authz.oauth2.provider.token.store.JwtAccessTokenConverter
;
import
org.springframework.security.access.AccessDeniedException
;
import
org.springframework.security.authentication.AnonymousAuthenticationToken
;
...
...
@@ -69,7 +70,7 @@ public class TokenKeyEndpoint {
* @param principal the currently authenticated user if there is one
* @return the key used to verify tokens
*/
@RequestMapping
(
value
=
"/oauth/token_key"
,
method
=
RequestMethod
.
GET
)
@RequestMapping
(
value
=
OAuth2Constants
.
ENDPOINT
.
ENDPOINT_TOKEN_KEY
,
method
=
RequestMethod
.
GET
)
@ResponseBody
public
Map
<
String
,
String
>
getKey
(
Principal
principal
)
{
if
((
principal
==
null
||
principal
instanceof
AnonymousAuthenticationToken
)
&&
!
converter
.
isPublic
())
{
...
...
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/OpenIdConnectUserInfoEndpoint.java
0 → 100644
浏览文件 @
173f7792
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org.maxkey.authz.oauth2.provider.userinfo.endpoint
;
import
java.util.Arrays
;
import
java.util.Date
;
import
java.util.HashMap
;
import
java.util.Set
;
import
java.util.UUID
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
org.maxkey.authn.SigninPrincipal
;
import
org.maxkey.authz.oauth2.common.OAuth2Constants
;
import
org.maxkey.authz.oauth2.common.exceptions.OAuth2Exception
;
import
org.maxkey.authz.oauth2.provider.ClientDetailsService
;
import
org.maxkey.authz.oauth2.provider.OAuth2Authentication
;
import
org.maxkey.authz.oauth2.provider.token.DefaultTokenServices
;
import
org.maxkey.constants.ContentType
;
import
org.maxkey.crypto.ReciprocalUtils
;
import
org.maxkey.crypto.jwt.encryption.service.JwtEncryptionAndDecryptionService
;
import
org.maxkey.crypto.jwt.encryption.service.impl.RecipientJwtEncryptionAndDecryptionServiceBuilder
;
import
org.maxkey.crypto.jwt.signer.service.JwtSigningAndValidationService
;
import
org.maxkey.crypto.jwt.signer.service.impl.SymmetricSigningAndValidationServiceBuilder
;
import
org.maxkey.domain.UserInfo
;
import
org.maxkey.domain.apps.oauth2.provider.ClientDetails
;
import
org.maxkey.persistence.service.AppsService
;
import
org.maxkey.persistence.service.UserInfoService
;
import
org.maxkey.util.JsonUtils
;
import
org.maxkey.util.StringGenerator
;
import
org.maxkey.web.HttpResponseAdapter
;
import
org.maxkey.web.WebConstants
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Qualifier
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.web.bind.annotation.RequestHeader
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.ResponseBody
;
import
com.nimbusds.jose.EncryptionMethod
;
import
com.nimbusds.jose.JWEAlgorithm
;
import
com.nimbusds.jose.JWEHeader
;
import
com.nimbusds.jose.JWSAlgorithm
;
import
com.nimbusds.jose.JWSHeader
;
import
com.nimbusds.jwt.EncryptedJWT
;
import
com.nimbusds.jwt.JWT
;
import
com.nimbusds.jwt.JWTClaimsSet
;
import
com.nimbusds.jwt.JWTClaimsSet.Builder
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
com.nimbusds.jwt.SignedJWT
;
@Api
(
tags
=
"2-1-OAuth v2.0 API文档模块"
)
@Controller
public
class
OpenIdConnectUserInfoEndpoint
{
final
static
Logger
_logger
=
LoggerFactory
.
getLogger
(
OpenIdConnectUserInfoEndpoint
.
class
);
@Autowired
@Qualifier
(
"oauth20JdbcClientDetailsService"
)
private
ClientDetailsService
clientDetailsService
;
@Autowired
@Qualifier
(
"oauth20TokenServices"
)
private
DefaultTokenServices
oauth20tokenServices
;
@Autowired
@Qualifier
(
"userInfoService"
)
private
UserInfoService
userInfoService
;
@Autowired
@Qualifier
(
"appsService"
)
protected
AppsService
appsService
;
@Autowired
@Qualifier
(
"jwtSignerValidationService"
)
private
JwtSigningAndValidationService
jwtSignerValidationService
;
@Autowired
@Qualifier
(
"jwtEncryptionService"
)
private
JwtEncryptionAndDecryptionService
jwtEnDecryptionService
;
private
SymmetricSigningAndValidationServiceBuilder
symmetricJwtSignerServiceBuilder
=
new
SymmetricSigningAndValidationServiceBuilder
();
private
RecipientJwtEncryptionAndDecryptionServiceBuilder
recipientJwtEnDecryptionServiceBuilder
=
new
RecipientJwtEncryptionAndDecryptionServiceBuilder
();
OAuthDefaultUserInfoAdapter
defaultOAuthUserInfoAdapter
=
new
OAuthDefaultUserInfoAdapter
();
@Autowired
protected
HttpResponseAdapter
httpResponseAdapter
;
@ApiOperation
(
value
=
"OIDC 用户信息接口"
,
notes
=
"传递Authorization参数access_token"
,
httpMethod
=
"GET"
)
@RequestMapping
(
value
=
OAuth2Constants
.
ENDPOINT
.
ENDPOINT_OPENID_CONNECT_USERINFO
)
@ResponseBody
public
String
connect10aUserInfo
(
@RequestHeader
(
value
=
"Authorization"
,
required
=
true
)
String
access_token
,
HttpServletRequest
request
,
HttpServletResponse
response
)
{
String
principal
=
""
;
if
(!
StringGenerator
.
uuidMatches
(
access_token
))
{
return
JsonUtils
.
gson2Json
(
accessTokenFormatError
(
access_token
));
}
OAuth2Authentication
oAuth2Authentication
=
null
;
try
{
oAuth2Authentication
=
oauth20tokenServices
.
loadAuthentication
(
access_token
);
principal
=((
SigninPrincipal
)
oAuth2Authentication
.
getPrincipal
()).
getUsername
();
Set
<
String
>
scopes
=
oAuth2Authentication
.
getOAuth2Request
().
getScope
();
ClientDetails
clientDetails
=
clientDetailsService
.
loadClientByClientId
(
oAuth2Authentication
.
getOAuth2Request
().
getClientId
());
UserInfo
userInfo
=
queryUserInfo
(
principal
);
String
userJson
=
""
;
Builder
jwtClaimsSetBuilder
=
new
JWTClaimsSet
.
Builder
();
SigninPrincipal
authentication
=
(
SigninPrincipal
)
oAuth2Authentication
.
getUserAuthentication
().
getPrincipal
();
jwtClaimsSetBuilder
.
claim
(
"sub"
,
userInfo
.
getId
());
jwtClaimsSetBuilder
.
claim
(
WebConstants
.
ONLINE_TICKET_NAME
,
authentication
.
getOnlineTicket
().
getTicketId
());
if
(
scopes
.
contains
(
"profile"
)){
jwtClaimsSetBuilder
.
claim
(
"name"
,
userInfo
.
getUsername
());
jwtClaimsSetBuilder
.
claim
(
"preferred_username"
,
userInfo
.
getDisplayName
());
jwtClaimsSetBuilder
.
claim
(
"given_name"
,
userInfo
.
getGivenName
());
jwtClaimsSetBuilder
.
claim
(
"family_name"
,
userInfo
.
getFamilyName
());
jwtClaimsSetBuilder
.
claim
(
"middle_name"
,
userInfo
.
getMiddleName
());
jwtClaimsSetBuilder
.
claim
(
"nickname"
,
userInfo
.
getNickName
());
jwtClaimsSetBuilder
.
claim
(
"profile"
,
"profile"
);
jwtClaimsSetBuilder
.
claim
(
"picture"
,
"picture"
);
jwtClaimsSetBuilder
.
claim
(
"website"
,
userInfo
.
getWebSite
());
String
gender
;
switch
(
userInfo
.
getGender
()){
case
UserInfo
.
GENDER
.
MALE
:
gender
=
"male"
;
break
;
case
UserInfo
.
GENDER
.
FEMALE
:
gender
=
"female"
;
break
;
default
:
gender
=
"unknown"
;
}
jwtClaimsSetBuilder
.
claim
(
"gender"
,
gender
);
jwtClaimsSetBuilder
.
claim
(
"zoneinfo"
,
userInfo
.
getTimeZone
());
jwtClaimsSetBuilder
.
claim
(
"locale"
,
userInfo
.
getLocale
());
jwtClaimsSetBuilder
.
claim
(
"updated_time"
,
userInfo
.
getModifiedDate
());
jwtClaimsSetBuilder
.
claim
(
"birthdate"
,
userInfo
.
getBirthDate
());
}
if
(
scopes
.
contains
(
"email"
)){
jwtClaimsSetBuilder
.
claim
(
"email"
,
userInfo
.
getWorkEmail
());
jwtClaimsSetBuilder
.
claim
(
"email_verified"
,
false
);
}
if
(
scopes
.
contains
(
"phone"
)){
jwtClaimsSetBuilder
.
claim
(
"phone_number"
,
userInfo
.
getWorkPhoneNumber
());
jwtClaimsSetBuilder
.
claim
(
"phone_number_verified"
,
false
);
}
if
(
scopes
.
contains
(
"address"
)){
HashMap
<
String
,
String
>
addressFields
=
new
HashMap
<
String
,
String
>();
addressFields
.
put
(
"country"
,
userInfo
.
getWorkCountry
());
addressFields
.
put
(
"region"
,
userInfo
.
getWorkRegion
());
addressFields
.
put
(
"locality"
,
userInfo
.
getWorkLocality
());
addressFields
.
put
(
"street_address"
,
userInfo
.
getWorkStreetAddress
());
addressFields
.
put
(
"formatted"
,
userInfo
.
getWorkAddressFormatted
());
addressFields
.
put
(
"postal_code"
,
userInfo
.
getWorkPostalCode
());
jwtClaimsSetBuilder
.
claim
(
"address"
,
addressFields
);
}
jwtClaimsSetBuilder
.
jwtID
(
UUID
.
randomUUID
().
toString
())
// set a random NONCE in the middle of it
.
audience
(
Arrays
.
asList
(
clientDetails
.
getClientId
()))
.
issueTime
(
new
Date
())
.
expirationTime
(
new
Date
(
new
Date
().
getTime
()+
clientDetails
.
getAccessTokenValiditySeconds
()*
1000
));
JWTClaimsSet
userInfoJWTClaims
=
jwtClaimsSetBuilder
.
build
();
JWT
userInfoJWT
=
null
;
JWSAlgorithm
signingAlg
=
jwtSignerValidationService
.
getDefaultSigningAlgorithm
();
if
(
clientDetails
.
getUserInfoEncryptedAlgorithm
()
!=
null
&&
!
clientDetails
.
getUserInfoEncryptedAlgorithm
().
equals
(
"none"
)
&&
clientDetails
.
getUserInfoEncryptionMethod
()
!=
null
&&
!
clientDetails
.
getUserInfoEncryptionMethod
().
equals
(
"none"
)
&&
clientDetails
.
getJwksUri
()!=
null
&&
clientDetails
.
getJwksUri
().
length
()>
4
)
{
//需要加密
response
.
setContentType
(
ContentType
.
APPLICATION_JWT_UTF8
);
JwtEncryptionAndDecryptionService
recipientJwtEnDecryptionService
=
recipientJwtEnDecryptionServiceBuilder
.
serviceBuilder
(
clientDetails
.
getJwksUri
());
if
(
recipientJwtEnDecryptionService
!=
null
)
{
JWEAlgorithm
jweAlgorithm
=
new
JWEAlgorithm
(
clientDetails
.
getUserInfoEncryptedAlgorithm
());
EncryptionMethod
encryptionMethod
=
new
EncryptionMethod
(
clientDetails
.
getUserInfoEncryptionMethod
());
EncryptedJWT
encryptedJWT
=
new
EncryptedJWT
(
new
JWEHeader
(
jweAlgorithm
,
encryptionMethod
),
userInfoJWTClaims
);
recipientJwtEnDecryptionService
.
encryptJwt
(
encryptedJWT
);
userJson
=
encryptedJWT
.
serialize
();
}
else
{
_logger
.
error
(
"Couldn't find encrypter for client: "
+
clientDetails
.
getClientId
());
HashMap
<
String
,
Object
>
authzException
=
new
HashMap
<
String
,
Object
>();
authzException
.
put
(
OAuth2Exception
.
ERROR
,
"error"
);
authzException
.
put
(
OAuth2Exception
.
DESCRIPTION
,
"Couldn't find encrypter for client: "
+
clientDetails
.
getClientId
());
return
JsonUtils
.
gson2Json
(
authzException
);
}
}
else
if
(
clientDetails
.
getUserInfoSigningAlgorithm
()!=
null
&&
!
clientDetails
.
getUserInfoSigningAlgorithm
().
equals
(
"none"
))
{
//需要签名
response
.
setContentType
(
ContentType
.
APPLICATION_JWT_UTF8
);
// signed ID token
if
(
signingAlg
.
equals
(
JWSAlgorithm
.
HS256
)
||
signingAlg
.
equals
(
JWSAlgorithm
.
HS384
)
||
signingAlg
.
equals
(
JWSAlgorithm
.
HS512
))
{
// sign it with the client's secret
String
client_secret
=
ReciprocalUtils
.
decoder
(
clientDetails
.
getClientSecret
());
JwtSigningAndValidationService
symmetricJwtSignerService
=
symmetricJwtSignerServiceBuilder
.
serviceBuilder
(
client_secret
);
if
(
symmetricJwtSignerService
!=
null
){
userInfoJWTClaims
=
new
JWTClaimsSet
.
Builder
(
userInfoJWTClaims
).
claim
(
"kid"
,
"SYMMETRIC-KEY"
).
build
();
userInfoJWT
=
new
SignedJWT
(
new
JWSHeader
(
signingAlg
),
userInfoJWTClaims
);
symmetricJwtSignerService
.
signJwt
((
SignedJWT
)
userInfoJWT
);
}
else
{
_logger
.
error
(
"Couldn't create symmetric validator for client "
+
clientDetails
.
getClientId
()
+
" without a client secret"
);
}
}
else
{
userInfoJWTClaims
=
new
JWTClaimsSet
.
Builder
(
userInfoJWTClaims
).
claim
(
"kid"
,
jwtSignerValidationService
.
getDefaultSignerKeyId
()).
build
();
userInfoJWT
=
new
SignedJWT
(
new
JWSHeader
(
signingAlg
),
userInfoJWTClaims
);
// sign it with the server's key
jwtSignerValidationService
.
signJwt
((
SignedJWT
)
userInfoJWT
);
}
userJson
=
userInfoJWT
.
serialize
();
}
else
{
//不需要加密和签名
response
.
setContentType
(
ContentType
.
APPLICATION_JSON_UTF8
);
// unsigned ID token
//userInfoJWT = new PlainJWT(userInfoJWTClaims);
userJson
=
JsonUtils
.
gson2Json
(
jwtClaimsSetBuilder
.
getClaims
());
}
return
userJson
;
}
catch
(
OAuth2Exception
e
){
HashMap
<
String
,
Object
>
authzException
=
new
HashMap
<
String
,
Object
>();
authzException
.
put
(
OAuth2Exception
.
ERROR
,
e
.
getOAuth2ErrorCode
());
authzException
.
put
(
OAuth2Exception
.
DESCRIPTION
,
e
.
getMessage
());
return
JsonUtils
.
object2Json
(
authzException
);
}
}
public
HashMap
<
String
,
Object
>
accessTokenFormatError
(
String
access_token
){
HashMap
<
String
,
Object
>
atfe
=
new
HashMap
<
String
,
Object
>();
atfe
.
put
(
OAuth2Exception
.
ERROR
,
"token Format Invalid"
);
atfe
.
put
(
OAuth2Exception
.
DESCRIPTION
,
"access Token Format Invalid , access_token : "
+
access_token
);
return
atfe
;
}
public
UserInfo
queryUserInfo
(
String
uid
){
_logger
.
debug
(
"uid : "
+
uid
);
UserInfo
userInfo
=
(
UserInfo
)
userInfoService
.
loadByUsername
(
uid
);
return
userInfo
;
}
public
void
setOauth20tokenServices
(
DefaultTokenServices
oauth20tokenServices
)
{
this
.
oauth20tokenServices
=
oauth20tokenServices
;
}
public
void
setUserInfoService
(
UserInfoService
userInfoService
)
{
this
.
userInfoService
=
userInfoService
;
}
//
//
// public void setJwtSignerValidationService(
// JwtSigningAndValidationService jwtSignerValidationService) {
// this.jwtSignerValidationService = jwtSignerValidationService;
// }
//
// public void setJwtEnDecryptionService(
// JwtEncryptionAndDecryptionService jwtEnDecryptionService) {
// this.jwtEnDecryptionService = jwtEnDecryptionService;
// }
}
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/UserInfoEndpoint.java
浏览文件 @
173f7792
...
...
@@ -17,32 +17,24 @@
package
org.maxkey.authz.oauth2.provider.userinfo.endpoint
;
import
java.util.Arrays
;
import
java.util.Date
;
import
java.util.Enumeration
;
import
java.util.HashMap
;
import
java.util.Set
;
import
java.util.UUID
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
org.maxkey.authn.SigninPrincipal
;
import
org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter
;
import
org.maxkey.authz.oauth2.common.OAuth2Constants
;
import
org.maxkey.authz.oauth2.common.exceptions.OAuth2Exception
;
import
org.maxkey.authz.oauth2.provider.ClientDetailsService
;
import
org.maxkey.authz.oauth2.provider.OAuth2Authentication
;
import
org.maxkey.authz.oauth2.provider.token.DefaultTokenServices
;
import
org.maxkey.constants.Boolean
;
import
org.maxkey.constants.ContentType
;
import
org.maxkey.crypto.ReciprocalUtils
;
import
org.maxkey.crypto.jwt.encryption.service.JwtEncryptionAndDecryptionService
;
import
org.maxkey.crypto.jwt.encryption.service.impl.RecipientJwtEncryptionAndDecryptionServiceBuilder
;
import
org.maxkey.crypto.jwt.signer.service.JwtSigningAndValidationService
;
import
org.maxkey.crypto.jwt.signer.service.impl.SymmetricSigningAndValidationServiceBuilder
;
import
org.maxkey.domain.UserInfo
;
import
org.maxkey.domain.apps.Apps
;
import
org.maxkey.domain.apps.oauth2.provider.ClientDetails
;
import
org.maxkey.persistence.service.AppsService
;
import
org.maxkey.persistence.service.UserInfoService
;
import
org.maxkey.util.AuthorizationHeaderUtils
;
...
...
@@ -50,7 +42,6 @@ import org.maxkey.util.Instance;
import
org.maxkey.util.JsonUtils
;
import
org.maxkey.util.StringGenerator
;
import
org.maxkey.web.HttpResponseAdapter
;
import
org.maxkey.web.WebConstants
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
...
...
@@ -59,26 +50,11 @@ import org.springframework.stereotype.Controller;
import
org.springframework.web.bind.annotation.RequestHeader
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.ResponseBody
;
import
com.nimbusds.jose.EncryptionMethod
;
import
com.nimbusds.jose.JWEAlgorithm
;
import
com.nimbusds.jose.JWEHeader
;
import
com.nimbusds.jose.JWSAlgorithm
;
import
com.nimbusds.jose.JWSHeader
;
import
com.nimbusds.jwt.EncryptedJWT
;
import
com.nimbusds.jwt.JWT
;
import
com.nimbusds.jwt.JWTClaimsSet
;
import
com.nimbusds.jwt.JWTClaimsSet.Builder
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
com.nimbusds.jwt.SignedJWT
;
@Api
(
tags
=
"2-1-OAuth v2.0 API文档模块"
)
@Controller
@RequestMapping
(
value
=
{
"/api"
})
public
class
UserInfoEndpoint
{
final
static
Logger
_logger
=
LoggerFactory
.
getLogger
(
UserInfoEndpoint
.
class
);
@Autowired
...
...
@@ -120,7 +96,7 @@ public class UserInfoEndpoint {
protected
HttpResponseAdapter
httpResponseAdapter
;
@ApiOperation
(
value
=
"OAuth 2.0 用户信息接口"
,
notes
=
"传递参数access_token"
,
httpMethod
=
"GET"
)
@RequestMapping
(
value
=
"/oauth/v20/me"
)
@RequestMapping
(
value
=
OAuth2Constants
.
ENDPOINT
.
ENDPOINT_USERINFO
)
public
void
apiV20UserInfo
(
@RequestParam
(
value
=
"access_token"
,
required
=
false
)
String
access_token
,
@RequestHeader
(
value
=
"authorization"
,
required
=
false
)
String
authorization_bearer
,
...
...
@@ -173,162 +149,6 @@ public class UserInfoEndpoint {
}
}
@ApiOperation
(
value
=
"OIDC 用户信息接口"
,
notes
=
"传递Authorization参数access_token"
,
httpMethod
=
"GET"
)
@RequestMapping
(
value
=
"/connect/v10/userinfo"
)
@ResponseBody
public
String
connect10aUserInfo
(
@RequestHeader
(
value
=
"Authorization"
,
required
=
true
)
String
access_token
,
HttpServletRequest
request
,
HttpServletResponse
response
)
{
String
principal
=
""
;
if
(!
StringGenerator
.
uuidMatches
(
access_token
))
{
return
JsonUtils
.
gson2Json
(
accessTokenFormatError
(
access_token
));
}
OAuth2Authentication
oAuth2Authentication
=
null
;
try
{
oAuth2Authentication
=
oauth20tokenServices
.
loadAuthentication
(
access_token
);
principal
=((
SigninPrincipal
)
oAuth2Authentication
.
getPrincipal
()).
getUsername
();
Set
<
String
>
scopes
=
oAuth2Authentication
.
getOAuth2Request
().
getScope
();
ClientDetails
clientDetails
=
clientDetailsService
.
loadClientByClientId
(
oAuth2Authentication
.
getOAuth2Request
().
getClientId
());
UserInfo
userInfo
=
queryUserInfo
(
principal
);
String
userJson
=
""
;
Builder
jwtClaimsSetBuilder
=
new
JWTClaimsSet
.
Builder
();
SigninPrincipal
authentication
=
(
SigninPrincipal
)
oAuth2Authentication
.
getUserAuthentication
().
getPrincipal
();
jwtClaimsSetBuilder
.
claim
(
"sub"
,
userInfo
.
getId
());
jwtClaimsSetBuilder
.
claim
(
WebConstants
.
ONLINE_TICKET_NAME
,
authentication
.
getOnlineTicket
().
getTicketId
());
if
(
scopes
.
contains
(
"profile"
)){
jwtClaimsSetBuilder
.
claim
(
"name"
,
userInfo
.
getUsername
());
jwtClaimsSetBuilder
.
claim
(
"preferred_username"
,
userInfo
.
getDisplayName
());
jwtClaimsSetBuilder
.
claim
(
"given_name"
,
userInfo
.
getGivenName
());
jwtClaimsSetBuilder
.
claim
(
"family_name"
,
userInfo
.
getFamilyName
());
jwtClaimsSetBuilder
.
claim
(
"middle_name"
,
userInfo
.
getMiddleName
());
jwtClaimsSetBuilder
.
claim
(
"nickname"
,
userInfo
.
getNickName
());
jwtClaimsSetBuilder
.
claim
(
"profile"
,
"profile"
);
jwtClaimsSetBuilder
.
claim
(
"picture"
,
"picture"
);
jwtClaimsSetBuilder
.
claim
(
"website"
,
userInfo
.
getWebSite
());
String
gender
;
switch
(
userInfo
.
getGender
()){
case
UserInfo
.
GENDER
.
MALE
:
gender
=
"male"
;
break
;
case
UserInfo
.
GENDER
.
FEMALE
:
gender
=
"female"
;
break
;
default
:
gender
=
"unknown"
;
}
jwtClaimsSetBuilder
.
claim
(
"gender"
,
gender
);
jwtClaimsSetBuilder
.
claim
(
"zoneinfo"
,
userInfo
.
getTimeZone
());
jwtClaimsSetBuilder
.
claim
(
"locale"
,
userInfo
.
getLocale
());
jwtClaimsSetBuilder
.
claim
(
"updated_time"
,
userInfo
.
getModifiedDate
());
jwtClaimsSetBuilder
.
claim
(
"birthdate"
,
userInfo
.
getBirthDate
());
}
if
(
scopes
.
contains
(
"email"
)){
jwtClaimsSetBuilder
.
claim
(
"email"
,
userInfo
.
getWorkEmail
());
jwtClaimsSetBuilder
.
claim
(
"email_verified"
,
false
);
}
if
(
scopes
.
contains
(
"phone"
)){
jwtClaimsSetBuilder
.
claim
(
"phone_number"
,
userInfo
.
getWorkPhoneNumber
());
jwtClaimsSetBuilder
.
claim
(
"phone_number_verified"
,
false
);
}
if
(
scopes
.
contains
(
"address"
)){
HashMap
<
String
,
String
>
addressFields
=
new
HashMap
<
String
,
String
>();
addressFields
.
put
(
"country"
,
userInfo
.
getWorkCountry
());
addressFields
.
put
(
"region"
,
userInfo
.
getWorkRegion
());
addressFields
.
put
(
"locality"
,
userInfo
.
getWorkLocality
());
addressFields
.
put
(
"street_address"
,
userInfo
.
getWorkStreetAddress
());
addressFields
.
put
(
"formatted"
,
userInfo
.
getWorkAddressFormatted
());
addressFields
.
put
(
"postal_code"
,
userInfo
.
getWorkPostalCode
());
jwtClaimsSetBuilder
.
claim
(
"address"
,
addressFields
);
}
jwtClaimsSetBuilder
.
jwtID
(
UUID
.
randomUUID
().
toString
())
// set a random NONCE in the middle of it
.
audience
(
Arrays
.
asList
(
clientDetails
.
getClientId
()))
.
issueTime
(
new
Date
())
.
expirationTime
(
new
Date
(
new
Date
().
getTime
()+
clientDetails
.
getAccessTokenValiditySeconds
()*
1000
));
JWTClaimsSet
userInfoJWTClaims
=
jwtClaimsSetBuilder
.
build
();
JWT
userInfoJWT
=
null
;
JWSAlgorithm
signingAlg
=
jwtSignerValidationService
.
getDefaultSigningAlgorithm
();
if
(
clientDetails
.
getUserInfoEncryptedAlgorithm
()
!=
null
&&
!
clientDetails
.
getUserInfoEncryptedAlgorithm
().
equals
(
"none"
)
&&
clientDetails
.
getUserInfoEncryptionMethod
()
!=
null
&&
!
clientDetails
.
getUserInfoEncryptionMethod
().
equals
(
"none"
)
&&
clientDetails
.
getJwksUri
()!=
null
&&
clientDetails
.
getJwksUri
().
length
()>
4
)
{
//需要加密
response
.
setContentType
(
ContentType
.
APPLICATION_JWT_UTF8
);
JwtEncryptionAndDecryptionService
recipientJwtEnDecryptionService
=
recipientJwtEnDecryptionServiceBuilder
.
serviceBuilder
(
clientDetails
.
getJwksUri
());
if
(
recipientJwtEnDecryptionService
!=
null
)
{
JWEAlgorithm
jweAlgorithm
=
new
JWEAlgorithm
(
clientDetails
.
getUserInfoEncryptedAlgorithm
());
EncryptionMethod
encryptionMethod
=
new
EncryptionMethod
(
clientDetails
.
getUserInfoEncryptionMethod
());
EncryptedJWT
encryptedJWT
=
new
EncryptedJWT
(
new
JWEHeader
(
jweAlgorithm
,
encryptionMethod
),
userInfoJWTClaims
);
recipientJwtEnDecryptionService
.
encryptJwt
(
encryptedJWT
);
userJson
=
encryptedJWT
.
serialize
();
}
else
{
_logger
.
error
(
"Couldn't find encrypter for client: "
+
clientDetails
.
getClientId
());
HashMap
<
String
,
Object
>
authzException
=
new
HashMap
<
String
,
Object
>();
authzException
.
put
(
OAuth2Exception
.
ERROR
,
"error"
);
authzException
.
put
(
OAuth2Exception
.
DESCRIPTION
,
"Couldn't find encrypter for client: "
+
clientDetails
.
getClientId
());
return
JsonUtils
.
gson2Json
(
authzException
);
}
}
else
if
(
clientDetails
.
getUserInfoSigningAlgorithm
()!=
null
&&
!
clientDetails
.
getUserInfoSigningAlgorithm
().
equals
(
"none"
))
{
//需要签名
response
.
setContentType
(
ContentType
.
APPLICATION_JWT_UTF8
);
// signed ID token
if
(
signingAlg
.
equals
(
JWSAlgorithm
.
HS256
)
||
signingAlg
.
equals
(
JWSAlgorithm
.
HS384
)
||
signingAlg
.
equals
(
JWSAlgorithm
.
HS512
))
{
// sign it with the client's secret
String
client_secret
=
ReciprocalUtils
.
decoder
(
clientDetails
.
getClientSecret
());
JwtSigningAndValidationService
symmetricJwtSignerService
=
symmetricJwtSignerServiceBuilder
.
serviceBuilder
(
client_secret
);
if
(
symmetricJwtSignerService
!=
null
){
userInfoJWTClaims
=
new
JWTClaimsSet
.
Builder
(
userInfoJWTClaims
).
claim
(
"kid"
,
"SYMMETRIC-KEY"
).
build
();
userInfoJWT
=
new
SignedJWT
(
new
JWSHeader
(
signingAlg
),
userInfoJWTClaims
);
symmetricJwtSignerService
.
signJwt
((
SignedJWT
)
userInfoJWT
);
}
else
{
_logger
.
error
(
"Couldn't create symmetric validator for client "
+
clientDetails
.
getClientId
()
+
" without a client secret"
);
}
}
else
{
userInfoJWTClaims
=
new
JWTClaimsSet
.
Builder
(
userInfoJWTClaims
).
claim
(
"kid"
,
jwtSignerValidationService
.
getDefaultSignerKeyId
()).
build
();
userInfoJWT
=
new
SignedJWT
(
new
JWSHeader
(
signingAlg
),
userInfoJWTClaims
);
// sign it with the server's key
jwtSignerValidationService
.
signJwt
((
SignedJWT
)
userInfoJWT
);
}
userJson
=
userInfoJWT
.
serialize
();
}
else
{
//不需要加密和签名
response
.
setContentType
(
ContentType
.
APPLICATION_JSON_UTF8
);
// unsigned ID token
//userInfoJWT = new PlainJWT(userInfoJWTClaims);
userJson
=
JsonUtils
.
gson2Json
(
jwtClaimsSetBuilder
.
getClaims
());
}
return
userJson
;
}
catch
(
OAuth2Exception
e
){
HashMap
<
String
,
Object
>
authzException
=
new
HashMap
<
String
,
Object
>();
authzException
.
put
(
OAuth2Exception
.
ERROR
,
e
.
getOAuth2ErrorCode
());
authzException
.
put
(
OAuth2Exception
.
DESCRIPTION
,
e
.
getMessage
());
return
JsonUtils
.
object2Json
(
authzException
);
}
}
public
HashMap
<
String
,
Object
>
accessTokenFormatError
(
String
access_token
){
HashMap
<
String
,
Object
>
atfe
=
new
HashMap
<
String
,
Object
>();
atfe
.
put
(
OAuth2Exception
.
ERROR
,
"token Format Invalid"
);
...
...
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/autoconfigure/Oauth20AutoConfiguration.java
浏览文件 @
173f7792
...
...
@@ -24,6 +24,7 @@ import java.security.spec.InvalidKeySpecException;
import
javax.servlet.Filter
;
import
javax.sql.DataSource
;
import
org.maxkey.authn.support.jwt.JwtLoginService
;
import
org.maxkey.authz.oauth2.common.OAuth2Constants
;
import
org.maxkey.authz.oauth2.provider.ClientDetailsService
;
import
org.maxkey.authz.oauth2.provider.OAuth2UserDetailsService
;
import
org.maxkey.authz.oauth2.provider.approval.TokenApprovalStore
;
...
...
@@ -79,7 +80,7 @@ public class Oauth20AutoConfiguration implements InitializingBean {
_logger
.
debug
(
"TokenEndpointAuthenticationFilter init "
);
FilterRegistrationBean
<
Filter
>
registration
=
new
FilterRegistrationBean
<
Filter
>();
registration
.
setFilter
(
new
TokenEndpointAuthenticationFilter
());
registration
.
addUrlPatterns
(
"/oauth/v20/token
/*"
);
registration
.
addUrlPatterns
(
OAuth2Constants
.
ENDPOINT
.
ENDPOINT_TOKEN
+
"
/*"
);
registration
.
setName
(
"TokenEndpointAuthenticationFilter"
);
registration
.
setOrder
(
1
);
return
registration
;
...
...
maxkey-web-manage/src/main/resources/application.properties
浏览文件 @
173f7792
...
...
@@ -212,8 +212,8 @@ maxkey.saml.v20.sp.issuing.entity.id=client.maxkey.org
#OIDC V1.0 METADATA configuration #
#############################################################################
maxkey.oidc.metadata.issuer
=
https://${maxkey.server.domain}/maxkey
maxkey.oidc.metadata.authorizationEndpoint
=
${maxkey.server.name}/maxkey/oauth/v20/authorize
maxkey.oidc.metadata.tokenEndpoint
=
${maxkey.server.name}/maxkey/oauth/v20/token
maxkey.oidc.metadata.authorizationEndpoint
=
${maxkey.server.name}/maxkey/
authz/
oauth/v20/authorize
maxkey.oidc.metadata.tokenEndpoint
=
${maxkey.server.name}/maxkey/
authz/
oauth/v20/token
maxkey.oidc.metadata.userinfoEndpoint
=
${maxkey.server.name}/maxkey/api/connect/userinfo
#############################################################################
...
...
maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyMvcConfig.java
浏览文件 @
173f7792
...
...
@@ -180,8 +180,8 @@ public class MaxKeyMvcConfig implements WebMvcConfigurer {
.
excludePathPatterns
(
"/authz/cas/v1/tickets/*"
)
//OAuth
.
addPathPatterns
(
"/oauth/v20/authorize"
)
.
addPathPatterns
(
"/oauth/v20/authorize/*"
)
.
addPathPatterns
(
"/
authz/
oauth/v20/authorize"
)
.
addPathPatterns
(
"/
authz/
oauth/v20/authorize/*"
)
//online ticket Validate
.
excludePathPatterns
(
"/onlineticket/ticketValidate"
)
...
...
maxkey-web-maxkey/src/main/resources/application-http.properties
浏览文件 @
173f7792
...
...
@@ -287,8 +287,8 @@ maxkey.support.wsfederation.logoutUrl=https://adfs.maxkey.top/adfs/ls/?wa=wsigno
#OIDC V1.0 METADATA configuration #
#############################################################################
maxkey.oidc.metadata.issuer
=
${maxkey.server.name}/maxkey
maxkey.oidc.metadata.authorizationEndpoint
=
${maxkey.server.name}/maxkey/oauth/v20/authorize
maxkey.oidc.metadata.tokenEndpoint
=
${maxkey.server.name}/maxkey/oauth/v20/token
maxkey.oidc.metadata.authorizationEndpoint
=
${maxkey.server.name}/maxkey/
authz/
oauth/v20/authorize
maxkey.oidc.metadata.tokenEndpoint
=
${maxkey.server.name}/maxkey/
authz/
oauth/v20/token
maxkey.oidc.metadata.userinfoEndpoint
=
${maxkey.server.name}/maxkey/api/connect/userinfo
#############################################################################
...
...
maxkey-web-maxkey/src/main/resources/application-https.properties
浏览文件 @
173f7792
...
...
@@ -287,8 +287,8 @@ maxkey.support.wsfederation.logoutUrl=https://adfs.maxkey.top/adfs/ls/?wa=wsigno
#OIDC V1.0 METADATA configuration #
#############################################################################
maxkey.oidc.metadata.issuer
=
${maxkey.server.name}/maxkey
maxkey.oidc.metadata.authorizationEndpoint
=
${maxkey.server.name}/maxkey/oauth/v20/authorize
maxkey.oidc.metadata.tokenEndpoint
=
${maxkey.server.name}/maxkey/oauth/v20/token
maxkey.oidc.metadata.authorizationEndpoint
=
${maxkey.server.name}/maxkey/
authz/
oauth/v20/authorize
maxkey.oidc.metadata.tokenEndpoint
=
${maxkey.server.name}/maxkey/
authz/
oauth/v20/token
maxkey.oidc.metadata.userinfoEndpoint
=
${maxkey.server.name}/maxkey/api/connect/userinfo
#############################################################################
...
...
maxkey-web-maxkey/src/main/resources/static/trusts/openid-configuration
浏览文件 @
173f7792
{
"issuer": "http://
login.connsec.com
",
"authorization_endpoint": "http://
login.connsec.com/sec
/oauth/v20/authorize",
"token_endpoint": "http://
login.connsec.com/sec
/oauth/v20/token",
"userinfo_endpoint": "http://
login.connsec.com/sec
/api/connect/v10/userinfo",
"issuer": "http://
sso.maxkey.top
",
"authorization_endpoint": "http://
sso.maxkey.top/maxkey/authz
/oauth/v20/authorize",
"token_endpoint": "http://
sso.maxkey.top/maxkey/authz
/oauth/v20/token",
"userinfo_endpoint": "http://
sso.maxkey.top/maxkey
/api/connect/v10/userinfo",
"revocation_endpoint": "",
"jwks_uri": "http://
login.connsec.com/sec
/key/jwk",
"jwks_uri": "http://
sso.maxkey.top/maxkey
/key/jwk",
"display_values_supported": [
"page",
"popup",
...
...
maxkey-web-maxkey/src/main/resources/templates/views/authorize/oauth_access_confirmation.ftl
浏览文件 @
173f7792
...
...
@@ -40,7 +40,7 @@
</table>
<!--<p>You hereby authorize "${model.client.clientId!}" to access your protected resources.</p>-->
<form
id=
"confirmationForm"
name=
"confirmationForm"
action=
"<@base/>/oauth/v20/authorize"
method=
"post"
>
<form
id=
"confirmationForm"
name=
"confirmationForm"
action=
"<@base/>/
authz/
oauth/v20/authorize"
method=
"post"
>
<input
id=
"user_oauth_approval"
name=
"user_oauth_approval"
value=
"true"
type=
"hidden"
/>
<label><input
class=
"button btn btn-primary mr-3"
name=
"authorize"
value=
'<@locale code="apps.oauth.approval.authorize"/>'
type=
"submit"
/></label>
</form>
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录