Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
符节科技
Jap
提交
624acc9e
Jap
项目概览
符节科技
/
Jap
大约 1 年 前同步成功
通知
91
Star
3
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Jap
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
624acc9e
编写于
9月 14, 2021
作者:
M
Mvbbb
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
✨
Add jap-http-api module
上级
6d0c837c
变更
23
隐藏空白更改
内联
并排
Showing
23 changed file
with
1440 addition
and
31 deletion
+1440
-31
jap-core/src/main/java/com/fujieid/jap/core/JapUserService.java
...re/src/main/java/com/fujieid/jap/core/JapUserService.java
+12
-13
jap-core/src/main/java/com/fujieid/jap/core/result/JapErrorCode.java
...c/main/java/com/fujieid/jap/core/result/JapErrorCode.java
+1
-1
jap-core/src/main/java/com/fujieid/jap/core/util/JapTokenHelper.java
...c/main/java/com/fujieid/jap/core/util/JapTokenHelper.java
+0
-14
jap-http-api/pom.xml
jap-http-api/pom.xml
+32
-0
jap-http-api/src/main/java/com/fujieid/jap/httpapi/HttpApiConfig.java
.../src/main/java/com/fujieid/jap/httpapi/HttpApiConfig.java
+236
-0
jap-http-api/src/main/java/com/fujieid/jap/httpapi/HttpApiStrategy.java
...rc/main/java/com/fujieid/jap/httpapi/HttpApiStrategy.java
+336
-0
jap-http-api/src/main/java/com/fujieid/jap/httpapi/enums/AuthInfoFieldEnum.java
...java/com/fujieid/jap/httpapi/enums/AuthInfoFieldEnum.java
+12
-0
jap-http-api/src/main/java/com/fujieid/jap/httpapi/enums/AuthSchemaEnum.java
...in/java/com/fujieid/jap/httpapi/enums/AuthSchemaEnum.java
+12
-0
jap-http-api/src/main/java/com/fujieid/jap/httpapi/enums/ForBearerTokenEnum.java
...ava/com/fujieid/jap/httpapi/enums/ForBearerTokenEnum.java
+14
-0
jap-http-api/src/main/java/com/fujieid/jap/httpapi/enums/HttpMethodEnum.java
...in/java/com/fujieid/jap/httpapi/enums/HttpMethodEnum.java
+11
-0
jap-http-api/src/main/java/com/fujieid/jap/httpapi/strategy/GetTokenFromResponseStrategy.java
...id/jap/httpapi/strategy/GetTokenFromResponseStrategy.java
+19
-0
jap-http-api/src/main/java/com/fujieid/jap/httpapi/strategy/RequestBodyToJapUserStrategy.java
...id/jap/httpapi/strategy/RequestBodyToJapUserStrategy.java
+23
-0
jap-http-api/src/main/java/com/fujieid/jap/httpapi/subject/DigestAuthorizationSubject.java
...jieid/jap/httpapi/subject/DigestAuthorizationSubject.java
+132
-0
jap-http-api/src/main/java/com/fujieid/jap/httpapi/subject/DigestWwwAuthenticateSubject.java
...eid/jap/httpapi/subject/DigestWwwAuthenticateSubject.java
+84
-0
jap-http-api/src/main/java/com/fujieid/jap/httpapi/subject/HttpAuthResponse.java
...ava/com/fujieid/jap/httpapi/subject/HttpAuthResponse.java
+49
-0
jap-http-api/src/main/java/com/fujieid/jap/httpapi/util/DigestMD5Util.java
...main/java/com/fujieid/jap/httpapi/util/DigestMD5Util.java
+57
-0
jap-http-api/src/main/java/com/fujieid/jap/httpapi/util/DigestSha256Util.java
...n/java/com/fujieid/jap/httpapi/util/DigestSha256Util.java
+163
-0
jap-http-api/src/main/java/com/fujieid/jap/httpapi/util/DigestUtil.java
...rc/main/java/com/fujieid/jap/httpapi/util/DigestUtil.java
+42
-0
jap-http-api/src/main/java/com/fujieid/jap/httpapi/util/HttpAuthUtil.java
.../main/java/com/fujieid/jap/httpapi/util/HttpAuthUtil.java
+47
-0
jap-http-api/src/main/java/com/fujieid/jap/httpapi/util/SimpleAuthJsonUtil.java
...java/com/fujieid/jap/httpapi/util/SimpleAuthJsonUtil.java
+41
-0
jap-http-api/src/main/java/com/fujieid/jap/httpapi/util/SubjectSerializeUtil.java
...va/com/fujieid/jap/httpapi/util/SubjectSerializeUtil.java
+77
-0
jap-http-api/src/main/java/com/fujieid/jap/httpapi/util/URLUtil.java
...i/src/main/java/com/fujieid/jap/httpapi/util/URLUtil.java
+36
-0
pom.xml
pom.xml
+4
-3
未找到文件。
jap-core/src/main/java/com/fujieid/jap/core/JapUserService.java
浏览文件 @
624acc9e
...
...
@@ -86,18 +86,6 @@ public interface JapUserService {
return
null
;
}
/**
* After logging in, bind the account of the third-party platform
*
* @param japUser User information of the third-party platform after successful login
* @param bindUserId The user id that needs to be bound, this is a user of the business system, not a user of the third-party platform.
* @return When binding successfully, return {@code true}, otherwise return {@code false}
*/
default
boolean
bindSocialUser
(
JapUser
japUser
,
String
bindUserId
)
{
return
false
;
}
/**
* Save the oauth login user information to the database and return JapUser
* <p>
...
...
@@ -106,11 +94,22 @@ public interface JapUserService {
* @param platform oauth2 platform name
* @param userInfo The basic user information returned by the OAuth platform
* @param tokenInfo The token information returned by the OAuth platform, developers can store tokens
* , type {@code com.fujieid.jap.oauth2.
token
.AccessToken}
* , type {@code com.fujieid.jap.oauth2.
helper
.AccessToken}
* @return When saving successfully, return {@code JapUser}, otherwise return {@code null}
*/
default
JapUser
createAndGetOauth2User
(
String
platform
,
Map
<
String
,
Object
>
userInfo
,
Object
tokenInfo
)
{
return
null
;
}
/**
* Save the http authed user information to the database and return JapUser
* <p>
* It is suitable for the {@code jap-http-api} module
* @param userinfo user information
* @return When saving successfully, return {@code JapUser}, otherwise return {@code null}
*/
default
JapUser
createAndGetHttpApiUser
(
Object
userinfo
){
return
null
;
}
}
jap-core/src/main/java/com/fujieid/jap/core/result/JapErrorCode.java
浏览文件 @
624acc9e
...
...
@@ -37,7 +37,7 @@ public enum JapErrorCode {
MISS_AUTHENTICATE_CONFIG
(
1005
,
"AuthenticateConfig is required."
),
MISS_ISSUER
(
1006
,
"OidcStrategy requires a issuer option."
),
MISS_CREDENTIALS
(
1007
,
"Missing credentials"
),
INVALID_GRANT_TYPE
(
1008
,
"The grant type is not supported by the authorization server, or the current client is not authorized for the grant type."
),
ERROR_HTTP_API_CONFIG
(
1008
,
"http api config error,please check"
)
;
private
final
int
errroCode
;
...
...
jap-core/src/main/java/com/fujieid/jap/core/util/JapTokenHelper.java
浏览文件 @
624acc9e
...
...
@@ -19,9 +19,7 @@ import cn.hutool.core.util.ObjectUtil;
import
com.baomidou.kisso.security.token.SSOToken
;
import
com.fujieid.jap.core.JapConst
;
import
com.fujieid.jap.core.context.JapAuthentication
;
import
com.fujieid.jap.core.exception.JapException
;
import
com.fujieid.jap.sso.JapSsoUtil
;
import
com.xkcoding.json.util.StringUtil
;
import
java.util.Map
;
...
...
@@ -36,26 +34,14 @@ public class JapTokenHelper {
public
static
void
saveUserToken
(
String
userId
,
String
token
)
{
if
(
StringUtil
.
isEmpty
(
userId
))
{
throw
new
JapException
(
"Failed to save user token, userid cannot be empty."
);
}
if
(
StringUtil
.
isEmpty
(
token
))
{
throw
new
JapException
(
"Failed to save user token, user token cannot be empty."
);
}
JapAuthentication
.
getContext
().
getCache
().
set
(
JapConst
.
USER_TOKEN_KEY
.
concat
(
userId
),
token
);
}
public
static
String
getUserToken
(
String
userId
)
{
if
(
StringUtil
.
isEmpty
(
userId
))
{
throw
new
JapException
(
"Failed to get user token, userid cannot be empty."
);
}
return
(
String
)
JapAuthentication
.
getContext
().
getCache
().
get
(
JapConst
.
USER_TOKEN_KEY
.
concat
(
userId
));
}
public
static
void
removeUserToken
(
String
userId
)
{
if
(
StringUtil
.
isEmpty
(
userId
))
{
throw
new
JapException
(
"Failed to remove user token, userid cannot be empty."
);
}
JapAuthentication
.
getContext
().
getCache
().
removeKey
(
JapConst
.
USER_TOKEN_KEY
.
concat
(
userId
));
}
...
...
jap-http-api/pom.xml
0 → 100644
浏览文件 @
624acc9e
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<parent>
<artifactId>
jap
</artifactId>
<groupId>
com.fujieid
</groupId>
<version>
${revision}
</version>
</parent>
<modelVersion>
4.0.0
</modelVersion>
<artifactId>
jap-http-api
</artifactId>
<version>
1.0.2
</version>
<groupId>
com.fujieid
</groupId>
<properties>
<maven.compiler.source>
8
</maven.compiler.source>
<maven.compiler.target>
8
</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>
com.fujieid
</groupId>
<artifactId>
jap-core
</artifactId>
</dependency>
<dependency>
<groupId>
me.zhyd.oauth
</groupId>
<artifactId>
JustAuth
</artifactId>
</dependency>
</dependencies>
</project>
jap-http-api/src/main/java/com/fujieid/jap/httpapi/HttpApiConfig.java
0 → 100644
浏览文件 @
624acc9e
package
com.fujieid.jap.httpapi
;
import
com.fujieid.jap.core.JapUser
;
import
com.fujieid.jap.core.config.AuthenticateConfig
;
import
com.fujieid.jap.httpapi.enums.AuthInfoFieldEnum
;
import
com.fujieid.jap.httpapi.enums.AuthSchemaEnum
;
import
com.fujieid.jap.httpapi.enums.ForBearerTokenEnum
;
import
com.fujieid.jap.httpapi.enums.HttpMethodEnum
;
import
com.fujieid.jap.httpapi.strategy.GetTokenFromResponseStrategy
;
import
com.fujieid.jap.httpapi.strategy.RequestBodyToJapUserStrategy
;
import
com.fujieid.jap.httpapi.util.SimpleAuthJsonUtil
;
import
com.xkcoding.json.JsonUtil
;
import
javax.servlet.http.HttpServletRequest
;
import
java.io.BufferedReader
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* Configuration file for http api authorization module
*
* @author zhihai.yu (mvbbb(a)foxmail.com)
* @version 1.0.0
* @since 1.0.0
*/
public
class
HttpApiConfig
extends
AuthenticateConfig
{
/**
* Schema for http authorization,defined by third-party system. eg:BASIC、DIGEST、BEARER.
*/
private
AuthSchemaEnum
authSchema
;
/**
* the http method for us to send request to third-party system, which is given by third-party system.
*/
private
HttpMethodEnum
httpMethod
;
/**
* the login url given by the third-party system.
*/
private
String
loginUrl
;
/**
* params/header/body
*/
private
AuthInfoFieldEnum
authInfoField
;
/**
* custom headers will be carried when request third-party system.
*/
private
Map
<
String
,
String
>
customHeaders
;
/**
* custom params will be carried when request third-party system.
*/
private
Map
<
String
,
String
>
customParams
;
/**
* custom body will be carried when request third-party system in json format.
*/
private
Map
<
String
,
String
>
customBody
;
/**
* define this field when authSchema is BEARER
*/
private
String
bearerTokenIssueUrl
;
/**
* if user auth info field is "body", by default, analyze user auth info by json format. ex:
* {
* "username":"admin",
* "password":"123456"
* }
* Developer's system should customize requestBodyToJapUserStrategy to get userinfo form request if user auth info is not this format.
*/
private
RequestBodyToJapUserStrategy
requestBodyToJapUserStrategy
=
new
RequestBodyToJapUserStrategy
(){
@Override
public
JapUser
decode
(
HttpServletRequest
request
)
throws
Exception
{
BufferedReader
reader
=
request
.
getReader
();
StringBuilder
body
=
new
StringBuilder
();
String
str
=
null
;
while
((
str
=
reader
.
readLine
())
!=
null
)
{
body
.
append
(
str
);
}
return
JsonUtil
.
toBean
(
body
.
toString
(),
JapUser
.
class
);
}
};
/**
* As we know Bearer auth need a token, but how to get this token? we should do a pre-auth to get this token, then store this token
* in developer's system. when user request for bearer auth, http-api module will query for user's token in our system.
* This field is used to define how to do pre-auth, how we get the token from third-party serve.
* When authSchema is BEARER you must define this field.
*/
private
ForBearerTokenEnum
forBearerTokenEnum
;
/**
* When do pre-auth for bearer auth, we get the response from third-party server which contains the token.
* Use this strategy to extract the token from response body.
* By default, search for field like "token":"xxxxxxxx" in response.
*/
private
GetTokenFromResponseStrategy
getTokenFromResponseStrategy
=
new
GetTokenFromResponseStrategy
()
{
@Override
public
String
getToken
(
String
body
)
{
try
{
int
i1
=
body
.
indexOf
(
"\"token\""
)+
7
;
int
i2
=
body
.
indexOf
(
':'
,
i1
);
int
i3
=
body
.
indexOf
(
"\""
,
i2
)+
1
;
int
i4
=
body
.
indexOf
(
"\""
,
i3
+
1
);
return
body
.
substring
(
i3
,
i4
);
}
catch
(
Exception
e
){
return
null
;
}
}
};
public
HttpApiConfig
()
{
}
public
HttpApiConfig
(
HttpApiConfig
httpApiConfig
,
String
loginUrl
)
{
this
.
authSchema
=
httpApiConfig
.
authSchema
;
this
.
httpMethod
=
httpApiConfig
.
httpMethod
;
this
.
loginUrl
=
loginUrl
;
this
.
authInfoField
=
httpApiConfig
.
authInfoField
;
this
.
customHeaders
=
httpApiConfig
.
customHeaders
;
this
.
customParams
=
httpApiConfig
.
customParams
;
this
.
customBody
=
httpApiConfig
.
customBody
;
this
.
bearerTokenIssueUrl
=
httpApiConfig
.
bearerTokenIssueUrl
;
this
.
requestBodyToJapUserStrategy
=
httpApiConfig
.
requestBodyToJapUserStrategy
;
this
.
forBearerTokenEnum
=
httpApiConfig
.
forBearerTokenEnum
;
this
.
getTokenFromResponseStrategy
=
httpApiConfig
.
getTokenFromResponseStrategy
;
}
public
AuthSchemaEnum
getAuthSchema
()
{
return
authSchema
;
}
public
HttpApiConfig
setAuthSchema
(
AuthSchemaEnum
authSchema
)
{
this
.
authSchema
=
authSchema
;
return
this
;
}
public
HttpMethodEnum
getHttpMethod
()
{
return
httpMethod
;
}
public
HttpApiConfig
setHttpMethod
(
HttpMethodEnum
httpMethod
)
{
this
.
httpMethod
=
httpMethod
;
return
this
;
}
public
String
getLoginUrl
()
{
return
loginUrl
;
}
public
HttpApiConfig
setLoginUrl
(
String
loginUrl
)
{
this
.
loginUrl
=
loginUrl
;
return
this
;
}
public
AuthInfoFieldEnum
getAuthInfoField
()
{
return
authInfoField
;
}
public
HttpApiConfig
setAuthInfoField
(
AuthInfoFieldEnum
authInfoField
)
{
this
.
authInfoField
=
authInfoField
;
return
this
;
}
public
Map
<
String
,
String
>
getCustomHeaders
()
{
return
customHeaders
;
}
public
HttpApiConfig
setCustomHeaders
(
Map
<
String
,
String
>
customHeaders
)
{
this
.
customHeaders
=
customHeaders
;
return
this
;
}
public
RequestBodyToJapUserStrategy
getRequestBodyToJapUserStrategy
()
{
return
requestBodyToJapUserStrategy
;
}
public
HttpApiConfig
setRequestBodyToJapUserStrategy
(
RequestBodyToJapUserStrategy
requestBodyToJapUserStrategy
)
{
this
.
requestBodyToJapUserStrategy
=
requestBodyToJapUserStrategy
;
return
this
;
}
public
Map
<
String
,
String
>
getCustomParams
()
{
return
customParams
;
}
public
Map
<
String
,
Object
>
getCustomParamsObjects
()
{
return
new
HashMap
<>(
customParams
);
}
public
HttpApiConfig
setCustomParams
(
Map
<
String
,
String
>
customParams
)
{
this
.
customParams
=
customParams
;
return
this
;
}
public
Map
<
String
,
String
>
getCustomBody
()
{
return
customBody
;
}
public
HttpApiConfig
setCustomBody
(
Map
<
String
,
String
>
customBody
)
{
this
.
customBody
=
customBody
;
return
this
;
}
public
ForBearerTokenEnum
getForBearerTokenEnum
()
{
return
forBearerTokenEnum
;
}
public
HttpApiConfig
setForBearerTokenEnum
(
ForBearerTokenEnum
forBearerTokenEnum
)
{
this
.
forBearerTokenEnum
=
forBearerTokenEnum
;
return
this
;
}
public
GetTokenFromResponseStrategy
getGetTokenFromResponseStrategy
()
{
return
getTokenFromResponseStrategy
;
}
public
HttpApiConfig
setGetTokenFromResponseStrategy
(
GetTokenFromResponseStrategy
getTokenFromResponseStrategy
)
{
this
.
getTokenFromResponseStrategy
=
getTokenFromResponseStrategy
;
return
this
;
}
public
String
getBearerTokenIssueUrl
()
{
return
bearerTokenIssueUrl
;
}
public
HttpApiConfig
setBearerTokenIssueUrl
(
String
bearerTokenIssueUrl
)
{
this
.
bearerTokenIssueUrl
=
bearerTokenIssueUrl
;
return
this
;
}
}
jap-http-api/src/main/java/com/fujieid/jap/httpapi/HttpApiStrategy.java
0 → 100644
浏览文件 @
624acc9e
package
com.fujieid.jap.httpapi
;
import
com.fujieid.jap.core.JapUser
;
import
com.fujieid.jap.core.JapUserService
;
import
com.fujieid.jap.core.cache.JapCache
;
import
com.fujieid.jap.core.config.AuthenticateConfig
;
import
com.fujieid.jap.core.config.JapConfig
;
import
com.fujieid.jap.core.exception.JapException
;
import
com.fujieid.jap.core.result.JapErrorCode
;
import
com.fujieid.jap.core.result.JapResponse
;
import
com.fujieid.jap.core.strategy.AbstractJapStrategy
;
import
com.fujieid.jap.httpapi.enums.AuthSchemaEnum
;
import
com.fujieid.jap.httpapi.enums.HttpMethodEnum
;
import
com.fujieid.jap.httpapi.subject.DigestAuthorizationSubject
;
import
com.fujieid.jap.httpapi.subject.DigestWwwAuthenticateSubject
;
import
com.fujieid.jap.httpapi.subject.HttpAuthResponse
;
import
com.fujieid.jap.httpapi.util.*
;
import
me.zhyd.oauth.utils.Base64Utils
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
/**
* The strategy for jap-http-api module to request third party system.
* @author zhihai.yu (mvbbb(a)foxmail.com)
* @version 1.0.0
* @since 1.0.0
*/
public
class
HttpApiStrategy
extends
AbstractJapStrategy
{
public
HttpApiStrategy
(
JapUserService
japUserService
,
JapConfig
japConfig
,
JapCache
japCache
)
{
super
(
japUserService
,
japConfig
,
japCache
);
}
@Override
public
JapResponse
authenticate
(
AuthenticateConfig
config
,
HttpServletRequest
request
,
HttpServletResponse
response
)
{
try
{
checkAuthenticateConfig
(
config
,
HttpApiConfig
.
class
);
}
catch
(
JapException
e
)
{
e
.
printStackTrace
();
return
JapResponse
.
error
(
e
.
getErrorCode
(),
e
.
getErrorMessage
());
}
HttpApiConfig
httpApiConfig
=
(
HttpApiConfig
)
config
;
return
this
.
doAuthenticate
(
httpApiConfig
,
request
,
response
);
}
private
JapResponse
doAuthenticate
(
HttpApiConfig
config
,
HttpServletRequest
servletRequest
,
HttpServletResponse
servletResponse
)
{
HttpAuthResponse
authResponse
=
null
;
JapUser
japUser
=
null
;
try
{
japUser
=
getJapUser
(
servletRequest
,
config
);
if
(
japUser
==
null
)
{
return
JapResponse
.
error
(
JapErrorCode
.
MISS_CREDENTIALS
);
}
switch
(
config
.
getAuthSchema
())
{
case
basic:
authResponse
=
doBasicAuth
(
japUser
,
config
,
servletResponse
);
break
;
case
digest:
authResponse
=
doDigestAuth
(
japUser
,
config
,
servletResponse
);
break
;
case
bearer:
authResponse
=
doBearerAuth
(
japUser
,
config
,
servletResponse
);
break
;
default
:
break
;
}
}
catch
(
JapException
e
){
return
JapResponse
.
error
(
e
.
getErrorCode
(),
e
.
getErrorMessage
());
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
if
(
authResponse
!=
null
&&
authResponse
.
isSuccess
())
{
if
(
config
.
getAuthSchema
()==
AuthSchemaEnum
.
basic
||
config
.
getAuthSchema
()==
AuthSchemaEnum
.
digest
){
japUserService
.
createAndGetHttpApiUser
(
japUser
);
}
return
JapResponse
.
success
(
authResponse
.
getBody
());
}
else
{
return
JapResponse
.
error
(
JapErrorCode
.
INVALID_PASSWORD
);
}
}
private
HttpAuthResponse
doDigestAuth
(
JapUser
japUser
,
HttpApiConfig
config
,
HttpServletResponse
servletResponse
)
{
/*
* send a request to third-party server to get a random number and encryption algorithm
* see: https://datatracker.ietf.org/doc/html/rfc2069#section-2.1.1
*/
HttpAuthResponse
responseForWWWAuth
=
HttpAuthUtil
.
sendRequest
(
config
.
getLoginUrl
(),
HttpMethodEnum
.
get
,
config
.
getCustomHeaders
(),
config
.
getCustomParams
(),
SimpleAuthJsonUtil
.
getJsonStrByParams
(
config
.
getCustomBody
()));
if
(
responseForWWWAuth
==
null
||
responseForWWWAuth
.
getHeaders
()==
null
){
return
null
;
}
HttpAuthResponse
result
=
null
;
String
wwwAuthenticate
=
null
;
try
{
wwwAuthenticate
=
responseForWWWAuth
.
getHeaders
().
get
(
"WWW-Authenticate"
).
get
(
0
).
replaceFirst
(
"Digest "
,
""
);
DigestWwwAuthenticateSubject
wwwAuthenticateSubject
=
(
DigestWwwAuthenticateSubject
)
SubjectSerializeUtil
.
deSerialize
(
DigestWwwAuthenticateSubject
.
class
,
wwwAuthenticate
);
String
username
=
japUser
.
getUsername
();
String
realm
=
wwwAuthenticateSubject
.
getRealm
();
String
password
=
japUser
.
getPassword
();
String
method
=
config
.
getHttpMethod
().
toString
().
toUpperCase
();
String
digestUri
=
URLUtil
.
getRelativeUri
(
config
.
getLoginUrl
());
String
nonce
=
wwwAuthenticateSubject
.
getNonce
();
String
qop
=
wwwAuthenticateSubject
.
getQop
();
String
nc
=
DigestUtil
.
getNc
();
String
cnonce
=
DigestUtil
.
getCnonce
();
String
opaque
=
wwwAuthenticateSubject
.
getOpaque
();
String
ha1
=
DigestMD5Util
.
encode
(
username
,
realm
,
password
);
String
ha2
=
DigestUtil
.
getHa2ByQop
(
qop
,
method
,
digestUri
);
String
response
=
DigestUtil
.
getResponseByQop
(
ha1
,
nonce
,
nc
,
cnonce
,
qop
,
ha2
);
DigestAuthorizationSubject
authorizationSubject
=
new
DigestAuthorizationSubject
()
.
setCnonce
(
cnonce
)
.
setQop
(
qop
)
.
setNc
(
nc
)
.
setNonce
(
nonce
)
.
setRealm
(
realm
)
.
setUsername
(
username
)
.
setUri
(
digestUri
)
.
setResponse
(
response
)
.
setAlgorithm
(
wwwAuthenticateSubject
.
getAlgorithm
())
.
setOpaque
(
opaque
);
String
authStr
=
SubjectSerializeUtil
.
serialize
(
authorizationSubject
);
// send authorization request
config
.
getCustomHeaders
().
put
(
"Authorization"
,
"Digest "
+
authStr
);
result
=
HttpAuthUtil
.
sendRequest
(
config
.
getLoginUrl
(),
config
.
getHttpMethod
(),
config
.
getCustomHeaders
(),
config
.
getCustomParams
(),
SimpleAuthJsonUtil
.
getJsonStrByParams
(
config
.
getCustomBody
()));
return
result
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
null
;
}
private
HttpAuthResponse
doBasicAuth
(
JapUser
japUser
,
HttpApiConfig
config
,
HttpServletResponse
servletResponse
)
{
/*
* see: The 'Basic' HTTP Authentication Scheme:https://datatracker.ietf.org/doc/html/rfc7617
*/
String
basicAuth
=
"Basic "
+
Base64Utils
.
encode
(
japUser
.
getUsername
()
+
":"
+
japUser
.
getPassword
());
config
.
getCustomHeaders
().
put
(
"authorization"
,
basicAuth
);
HttpAuthResponse
httpAuthResponse
=
HttpAuthUtil
.
sendRequest
(
config
.
getLoginUrl
(),
config
.
getHttpMethod
(),
config
.
getCustomHeaders
(),
config
.
getCustomParams
(),
SimpleAuthJsonUtil
.
getJsonStrByParams
(
config
.
getCustomBody
()));
return
httpAuthResponse
;
}
private
HttpAuthResponse
sendBearerTokenAuthRequest
(
String
token
,
HttpApiConfig
config
){
String
bearerToken
=
"Bearer "
+
token
;
config
.
getCustomHeaders
().
put
(
"Authorization"
,
bearerToken
);
HttpAuthResponse
result
=
HttpAuthUtil
.
sendRequest
(
config
.
getLoginUrl
(),
config
.
getHttpMethod
(),
config
.
getCustomHeaders
(),
config
.
getCustomParams
(),
SimpleAuthJsonUtil
.
getJsonStrByParams
(
config
.
getCustomBody
()));
return
result
;
}
private
HttpAuthResponse
doBearerAuth
(
JapUser
japUser
,
HttpApiConfig
config
,
HttpServletResponse
servletResponse
)
{
JapUser
japUserInDb
=
japUserService
.
getByName
(
japUser
.
getUsername
());
String
token
=
null
;
if
(
japUserInDb
==
null
||
japUserInDb
.
getToken
()
==
null
)
{
token
=
doPreAuthForBearerToken
(
japUser
,
config
,
servletResponse
);
}
else
{
token
=
japUserInDb
.
getToken
();
}
HttpAuthResponse
result
=
sendBearerTokenAuthRequest
(
token
,
config
);
// old token expired, request for new token
if
(
result
==
null
||!
result
.
isSuccess
()){
String
newToken
=
doPreAuthForBearerToken
(
japUser
,
config
,
servletResponse
);
result
=
sendBearerTokenAuthRequest
(
newToken
,
config
);
}
return
result
;
}
/**
* do a pre-auth in Bearer auth to get token for this user
*
* @param japUser
* @param config
* @param servletResponse
*/
private
String
doPreAuthForBearerToken
(
JapUser
japUser
,
HttpApiConfig
config
,
HttpServletResponse
servletResponse
)
{
HttpAuthResponse
response
=
null
;
// clean old auth token
config
.
getCustomHeaders
().
remove
(
"Authorization"
);
config
.
getCustomHeaders
().
remove
(
"authorization"
);
switch
(
config
.
getForBearerTokenEnum
())
{
case
by_basic:
response
=
this
.
doBasicAuth
(
japUser
,
new
HttpApiConfig
(
config
,
config
.
getBearerTokenIssueUrl
()),
servletResponse
);
break
;
case
by_digest:
response
=
this
.
doDigestAuth
(
japUser
,
new
HttpApiConfig
(
config
,
config
.
getBearerTokenIssueUrl
()),
servletResponse
);
break
;
case
by_header:
config
.
getCustomHeaders
().
put
(
"username"
,
japUser
.
getUsername
());
config
.
getCustomHeaders
().
put
(
"password"
,
japUser
.
getPassword
());
response
=
HttpAuthUtil
.
sendRequest
(
config
.
getLoginUrl
(),
config
.
getHttpMethod
(),
config
.
getCustomHeaders
(),
config
.
getCustomParams
(),
SimpleAuthJsonUtil
.
getJsonStrByParams
(
config
.
getCustomBody
()));
break
;
case
by_params:
config
.
getCustomParams
().
put
(
"username"
,
japUser
.
getUsername
());
config
.
getCustomParams
().
put
(
"password"
,
japUser
.
getPassword
());
response
=
HttpAuthUtil
.
sendRequest
(
config
.
getLoginUrl
(),
config
.
getHttpMethod
(),
config
.
getCustomHeaders
(),
config
.
getCustomParams
(),
SimpleAuthJsonUtil
.
getJsonStrByParams
(
config
.
getCustomBody
()));
break
;
case
by_body:
String
body
=
SimpleAuthJsonUtil
.
getJsonStrByJapUserAndParams
(
japUser
,
config
.
getCustomBody
());
response
=
HttpAuthUtil
.
sendRequest
(
config
.
getLoginUrl
(),
config
.
getHttpMethod
(),
config
.
getCustomHeaders
(),
config
.
getCustomParams
(),
body
);
break
;
default
:
break
;
}
// pre-auth field
if
(
response
==
null
||!
response
.
isSuccess
())
{
return
null
;
}
// get token from response body
String
token
=
config
.
getGetTokenFromResponseStrategy
().
getToken
(
response
.
getBody
());
if
(
token
==
null
||
token
.
length
()
==
0
)
{
return
null
;
}
// save jap user to db
japUser
.
setToken
(
token
);
japUserService
.
createAndGetHttpApiUser
(
japUser
);
return
token
;
}
/**
* get user information from request according to http api config.
*
* @param request
* @param config
* @return jap user contains username and password
*/
public
JapUser
getJapUser
(
HttpServletRequest
request
,
HttpApiConfig
config
)
{
JapUser
japUser
=
null
;
String
username
=
null
;
String
password
=
null
;
switch
(
config
.
getAuthInfoField
())
{
case
params:
username
=
request
.
getParameter
(
"username"
);
password
=
request
.
getParameter
(
"password"
);
japUser
=
new
JapUser
().
setUsername
(
username
).
setPassword
(
password
);
break
;
case
header:
username
=
request
.
getHeader
(
"username"
);
password
=
request
.
getHeader
(
"password"
);
japUser
=
new
JapUser
().
setUsername
(
username
).
setPassword
(
password
);
break
;
case
body:
try
{
// get auth info body from request body.
japUser
=
config
.
getRequestBodyToJapUserStrategy
().
decode
(
request
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
break
;
default
:
break
;
}
if
(
null
==
japUser
||
null
==
japUser
.
getUsername
())
{
return
null
;
}
return
japUser
;
}
/**
* check http api config.
* NOTICE:
* 1. When use "GET" as request method, custom body is not supported.
* 2. Can not custom body and params at the same time.
* @param sourceConfig The parameters passed in by the caller
* @param targetConfigClazz The actual parameter class type
* @throws JapException
*/
@Override
protected
void
checkAuthenticateConfig
(
AuthenticateConfig
sourceConfig
,
Class
<?>
targetConfigClazz
)
throws
JapException
{
super
.
checkAuthenticateConfig
(
sourceConfig
,
targetConfigClazz
);
HttpApiConfig
config
=
(
HttpApiConfig
)
sourceConfig
;
if
(
config
==
null
||
config
.
getAuthSchema
()
==
null
||
config
.
getHttpMethod
()
==
null
||
config
.
getLoginUrl
()
==
null
||
config
.
getAuthInfoField
()
==
null
||
(
config
.
getHttpMethod
()==
HttpMethodEnum
.
get
&&(
config
.
getCustomBody
()!=
null
&&
config
.
getCustomBody
().
size
()!=
0
))||
((
config
.
getCustomBody
()!=
null
&&
config
.
getCustomBody
().
size
()!=
0
)&&(
config
.
getCustomParams
()!=
null
&&
config
.
getCustomParams
().
size
()!=
0
))
){
throw
new
JapException
(
JapErrorCode
.
ERROR_HTTP_API_CONFIG
);
}
}
}
jap-http-api/src/main/java/com/fujieid/jap/httpapi/enums/AuthInfoFieldEnum.java
0 → 100644
浏览文件 @
624acc9e
package
com.fujieid.jap.httpapi.enums
;
/**
* @author zhihai.yu (mvbbb(a)foxmail.com)
* @version 1.0.0
* @since 1.0.0
*/
public
enum
AuthInfoFieldEnum
{
header
,
params
,
body
}
jap-http-api/src/main/java/com/fujieid/jap/httpapi/enums/AuthSchemaEnum.java
0 → 100644
浏览文件 @
624acc9e
package
com.fujieid.jap.httpapi.enums
;
/**
* @author zhihai.yu (mvbbb(a)foxmail.com)
* @version 1.0.0
* @since 1.0.0
*/
public
enum
AuthSchemaEnum
{
basic
,
digest
,
bearer
}
jap-http-api/src/main/java/com/fujieid/jap/httpapi/enums/ForBearerTokenEnum.java
0 → 100644
浏览文件 @
624acc9e
package
com.fujieid.jap.httpapi.enums
;
/**
* @author zhihai.yu (mvbbb(a)foxmail.com)
* @version 1.0.0
* @since 1.0.0
*/
public
enum
ForBearerTokenEnum
{
by_header
,
by_params
,
by_body
,
by_basic
,
by_digest
}
jap-http-api/src/main/java/com/fujieid/jap/httpapi/enums/HttpMethodEnum.java
0 → 100644
浏览文件 @
624acc9e
package
com.fujieid.jap.httpapi.enums
;
/**
* @author zhihai.yu (mvbbb(a)foxmail.com)
* @version 1.0.0
* @since 1.0.0
*/
public
enum
HttpMethodEnum
{
post
,
get
}
jap-http-api/src/main/java/com/fujieid/jap/httpapi/strategy/GetTokenFromResponseStrategy.java
0 → 100644
浏览文件 @
624acc9e
package
com.fujieid.jap.httpapi.strategy
;
/**
* Define how to get token from the third-party server's response when request to issue a bearer token
*
* @author zhihai.yu (mvbbb(a)foxmail.com)
* @version 1.0.0
* @since 1.0.0
*/
@FunctionalInterface
public
interface
GetTokenFromResponseStrategy
{
/**
* get token from body
* @param body response body
* @return token
*/
String
getToken
(
String
body
);
}
jap-http-api/src/main/java/com/fujieid/jap/httpapi/strategy/RequestBodyToJapUserStrategy.java
0 → 100644
浏览文件 @
624acc9e
package
com.fujieid.jap.httpapi.strategy
;
import
com.fujieid.jap.core.JapUser
;
import
javax.servlet.http.HttpServletRequest
;
/**
* Implement this functional interface if your auth info in the request body is not standard json format.
*
* @author zhihai.yu (mvbbb(a)foxmail.com)
* @version 1.0.0
* @since 1.0.0
*/
@FunctionalInterface
public
interface
RequestBodyToJapUserStrategy
{
/**
* get a JapUser from request
* @param request request
* @return JapUser
* @throws Exception
*/
JapUser
decode
(
HttpServletRequest
request
)
throws
Exception
;
}
jap-http-api/src/main/java/com/fujieid/jap/httpapi/subject/DigestAuthorizationSubject.java
0 → 100644
浏览文件 @
624acc9e
package
com.fujieid.jap.httpapi.subject
;
/**
* The Authorization Request Header
* @see <a href="https://en.wikipedia.org/wiki/Digest_access_authentication" target="_blank">https://en.wikipedia.org/wiki/Digest_access_authentication</a>
* @see <a href="https://datatracker.ietf.org/doc/html/rfc2069#section-2.1.2" target="_blank">https://datatracker.ietf.org/doc/html/rfc2069#section-2.1.2</a>
* @author zhihai.yu (mvbbb(a)foxmail.com)
* @version 1.0.0
* @since 1.0.0
*/
public
class
DigestAuthorizationSubject
{
private
String
username
;
private
String
realm
;
private
String
nonce
;
private
String
uri
;
private
String
response
;
private
String
qop
;
private
String
nc
;
private
String
cnonce
;
private
String
pop
;
private
String
opaque
;
private
String
digest
;
private
String
algorithm
;
public
String
getQop
()
{
return
qop
;
}
public
DigestAuthorizationSubject
setQop
(
String
qop
)
{
this
.
qop
=
qop
;
return
this
;
}
public
String
getUsername
()
{
return
username
;
}
public
DigestAuthorizationSubject
setUsername
(
String
username
)
{
this
.
username
=
username
;
return
this
;
}
public
String
getRealm
()
{
return
realm
;
}
public
DigestAuthorizationSubject
setRealm
(
String
realm
)
{
this
.
realm
=
realm
;
return
this
;
}
public
String
getNonce
()
{
return
nonce
;
}
public
DigestAuthorizationSubject
setNonce
(
String
nonce
)
{
this
.
nonce
=
nonce
;
return
this
;
}
public
String
getUri
()
{
return
uri
;
}
public
DigestAuthorizationSubject
setUri
(
String
uri
)
{
this
.
uri
=
uri
;
return
this
;
}
public
String
getPop
()
{
return
pop
;
}
public
DigestAuthorizationSubject
setPop
(
String
pop
)
{
this
.
pop
=
pop
;
return
this
;
}
public
String
getNc
()
{
return
nc
;
}
public
DigestAuthorizationSubject
setNc
(
String
nc
)
{
this
.
nc
=
nc
;
return
this
;
}
public
String
getCnonce
()
{
return
cnonce
;
}
public
DigestAuthorizationSubject
setCnonce
(
String
cnonce
)
{
this
.
cnonce
=
cnonce
;
return
this
;
}
public
String
getResponse
()
{
return
response
;
}
public
DigestAuthorizationSubject
setResponse
(
String
response
)
{
this
.
response
=
response
;
return
this
;
}
public
String
getOpaque
()
{
return
opaque
;
}
public
DigestAuthorizationSubject
setOpaque
(
String
opaque
)
{
this
.
opaque
=
opaque
;
return
this
;
}
public
String
getDigest
()
{
return
digest
;
}
public
DigestAuthorizationSubject
setDigest
(
String
digest
)
{
this
.
digest
=
digest
;
return
this
;
}
public
String
getAlgorithm
()
{
return
algorithm
;
}
public
DigestAuthorizationSubject
setAlgorithm
(
String
algorithm
)
{
this
.
algorithm
=
algorithm
;
return
this
;
}
}
jap-http-api/src/main/java/com/fujieid/jap/httpapi/subject/DigestWwwAuthenticateSubject.java
0 → 100644
浏览文件 @
624acc9e
package
com.fujieid.jap.httpapi.subject
;
/**
* The WWW-Authenticate Response Header
* @see <a href="https://datatracker.ietf.org/doc/html/rfc2069#section-2.1.1" target="_blank">https://datatracker.ietf.org/doc/html/rfc2069#section-2.1.1</a>
* @author zhihai.yu (mvbbb(a)foxmail.com)
* @version 1.0.0
* @since 1.0.0
*/
public
class
DigestWwwAuthenticateSubject
{
private
String
realm
;
private
String
domain
;
private
String
nonce
;
private
String
opaque
;
private
String
algorithm
;
private
String
stale
;
private
String
qop
;
public
String
getQop
()
{
return
qop
;
}
public
DigestWwwAuthenticateSubject
setQop
(
String
qop
)
{
this
.
qop
=
qop
;
return
this
;
}
public
DigestWwwAuthenticateSubject
()
{
}
public
String
getRealm
()
{
return
realm
;
}
public
DigestWwwAuthenticateSubject
setRealm
(
String
realm
)
{
this
.
realm
=
realm
;
return
this
;
}
public
String
getDomain
()
{
return
domain
;
}
public
DigestWwwAuthenticateSubject
setDomain
(
String
domain
)
{
this
.
domain
=
domain
;
return
this
;
}
public
String
getNonce
()
{
return
nonce
;
}
public
DigestWwwAuthenticateSubject
setNonce
(
String
nonce
)
{
this
.
nonce
=
nonce
;
return
this
;
}
public
String
getOpaque
()
{
return
opaque
;
}
public
DigestWwwAuthenticateSubject
setOpaque
(
String
opaque
)
{
this
.
opaque
=
opaque
;
return
this
;
}
public
String
getAlgorithm
()
{
return
algorithm
;
}
public
DigestWwwAuthenticateSubject
setAlgorithm
(
String
algorithm
)
{
this
.
algorithm
=
algorithm
;
return
this
;
}
public
String
getStale
()
{
return
stale
;
}
public
DigestWwwAuthenticateSubject
setStale
(
String
stale
)
{
this
.
stale
=
stale
;
return
this
;
}
}
jap-http-api/src/main/java/com/fujieid/jap/httpapi/subject/HttpAuthResponse.java
0 → 100644
浏览文件 @
624acc9e
package
com.fujieid.jap.httpapi.subject
;
import
java.util.List
;
import
java.util.Map
;
/**
* packaging auth result
* @author zhihai.yu (mvbbb(a)foxmail.com)
* @version 1.0.0
* @since 1.0.0
*/
public
class
HttpAuthResponse
{
private
boolean
success
;
private
String
body
;
private
Map
<
String
,
List
<
String
>>
headers
;
public
HttpAuthResponse
(
boolean
success
,
String
body
,
Map
<
String
,
List
<
String
>>
headers
)
{
this
.
success
=
success
;
this
.
body
=
body
;
this
.
headers
=
headers
;
}
public
boolean
isSuccess
()
{
return
success
;
}
public
HttpAuthResponse
setSuccess
(
boolean
success
)
{
this
.
success
=
success
;
return
this
;
}
public
String
getBody
()
{
return
body
;
}
public
HttpAuthResponse
setBody
(
String
body
)
{
this
.
body
=
body
;
return
this
;
}
public
Map
<
String
,
List
<
String
>>
getHeaders
()
{
return
headers
;
}
public
HttpAuthResponse
setHeaders
(
Map
<
String
,
List
<
String
>>
headers
)
{
this
.
headers
=
headers
;
return
this
;
}
}
jap-http-api/src/main/java/com/fujieid/jap/httpapi/util/DigestMD5Util.java
0 → 100644
浏览文件 @
624acc9e
package
com.fujieid.jap.httpapi.util
;
import
java.security.MessageDigest
;
import
java.security.NoSuchAlgorithmException
;
/**
* Splice strings by ":", and encode using md5. eg:"MD5(MD5(username:realm:password):nonce:cnonce)"
* @author zhihai.yu (mvbbb(a)foxmail.com)
* @version 1.0.0
* @since 1.0.0
*/
public
final
class
DigestMD5Util
{
private
final
static
String
[]
HEX_ARRAY
=
{
"0"
,
"1"
,
"2"
,
"3"
,
"4"
,
"5"
,
"6"
,
"7"
,
"8"
,
"9"
,
"a"
,
"b"
,
"c"
,
"d"
,
"e"
,
"f"
};
public
static
String
encode
(
String
...
strs
){
StringBuilder
stringBuffer
=
new
StringBuilder
();
boolean
isFirst
=
true
;
for
(
String
str:
strs
){
if
(
isFirst
){
stringBuffer
.
append
(
str
);
isFirst
=
false
;
}
else
{
stringBuffer
.
append
(
":"
).
append
(
str
);
}
}
// Create an information summary with MD5 algorithm
MessageDigest
md
=
null
;
try
{
md
=
MessageDigest
.
getInstance
(
"MD5"
);
}
catch
(
NoSuchAlgorithmException
e
)
{
e
.
printStackTrace
();
}
byte
[]
bytes
=
md
.
digest
(
stringBuffer
.
toString
().
getBytes
());
return
byteArrayToHex
(
bytes
);
}
private
static
String
byteArrayToHex
(
byte
[]
b
){
StringBuffer
sb
=
new
StringBuffer
();
for
(
int
i
=
0
;
i
<
b
.
length
;
i
++)
{
sb
.
append
(
byteToHex
(
b
[
i
]));
}
return
sb
.
toString
();
}
public
static
String
byteToHex
(
byte
b
)
{
int
n
=
b
;
if
(
n
<
0
){
n
=
n
+
256
;
}
int
d1
=
n
/
16
;
int
d2
=
n
%
16
;
return
HEX_ARRAY
[
d1
]+
HEX_ARRAY
[
d2
];
}
}
jap-http-api/src/main/java/com/fujieid/jap/httpapi/util/DigestSha256Util.java
0 → 100644
浏览文件 @
624acc9e
package
com.fujieid.jap.httpapi.util
;
import
java.nio.ByteBuffer
;
import
java.nio.IntBuffer
;
/**
* refer: https://github.com/meyfa/java-sha256/blob/master/src/main/java/net/meyfa/sha256/Sha256.java
* @author zhihai.yu (mvbbb(a)foxmail.com)
* @version 1.0.0
* @since 1.0.0
*/
public
class
DigestSha256Util
{
private
static
final
int
[]
K
=
{
0x428a2f98
,
0x71374491
,
0xb5c0fbcf
,
0xe9b5dba5
,
0x3956c25b
,
0x59f111f1
,
0x923f82a4
,
0xab1c5ed5
,
0xd807aa98
,
0x12835b01
,
0x243185be
,
0x550c7dc3
,
0x72be5d74
,
0x80deb1fe
,
0x9bdc06a7
,
0xc19bf174
,
0xe49b69c1
,
0xefbe4786
,
0x0fc19dc6
,
0x240ca1cc
,
0x2de92c6f
,
0x4a7484aa
,
0x5cb0a9dc
,
0x76f988da
,
0x983e5152
,
0xa831c66d
,
0xb00327c8
,
0xbf597fc7
,
0xc6e00bf3
,
0xd5a79147
,
0x06ca6351
,
0x14292967
,
0x27b70a85
,
0x2e1b2138
,
0x4d2c6dfc
,
0x53380d13
,
0x650a7354
,
0x766a0abb
,
0x81c2c92e
,
0x92722c85
,
0xa2bfe8a1
,
0xa81a664b
,
0xc24b8b70
,
0xc76c51a3
,
0xd192e819
,
0xd6990624
,
0xf40e3585
,
0x106aa070
,
0x19a4c116
,
0x1e376c08
,
0x2748774c
,
0x34b0bcb5
,
0x391c0cb3
,
0x4ed8aa4a
,
0x5b9cca4f
,
0x682e6ff3
,
0x748f82ee
,
0x78a5636f
,
0x84c87814
,
0x8cc70208
,
0x90befffa
,
0xa4506ceb
,
0xbef9a3f7
,
0xc67178f2
};
private
static
final
int
[]
H0
=
{
0x6a09e667
,
0xbb67ae85
,
0x3c6ef372
,
0xa54ff53a
,
0x510e527f
,
0x9b05688c
,
0x1f83d9ab
,
0x5be0cd19
};
private
static
final
int
BLOCK_BITS
=
512
;
private
static
final
int
BLOCK_BYTES
=
BLOCK_BITS
/
8
;
// working arrays
private
static
final
int
[]
W
=
new
int
[
64
];
private
static
final
int
[]
H
=
new
int
[
8
];
private
static
final
int
[]
TEMP
=
new
int
[
8
];
/**
* Hashes the given message with SHA-256 and returns the hash.
*
* @param message The bytes to hash.
* @return The hash's bytes.
*/
public
static
byte
[]
hash
(
byte
[]
message
)
{
// let H = H0
System
.
arraycopy
(
H0
,
0
,
H
,
0
,
H0
.
length
);
// initialize all words
int
[]
words
=
pad
(
message
);
// enumerate all blocks (each containing 16 words)
for
(
int
i
=
0
,
n
=
words
.
length
/
16
;
i
<
n
;
++
i
)
{
// initialize W from the block's words
System
.
arraycopy
(
words
,
i
*
16
,
W
,
0
,
16
);
for
(
int
t
=
16
;
t
<
W
.
length
;
++
t
)
{
W
[
t
]
=
smallSig1
(
W
[
t
-
2
])
+
W
[
t
-
7
]
+
smallSig0
(
W
[
t
-
15
])
+
W
[
t
-
16
];
}
// let TEMP = H
System
.
arraycopy
(
H
,
0
,
TEMP
,
0
,
H
.
length
);
// operate on TEMP
for
(
int
t
=
0
;
t
<
W
.
length
;
++
t
)
{
int
t1
=
TEMP
[
7
]
+
bigSig1
(
TEMP
[
4
])
+
ch
(
TEMP
[
4
],
TEMP
[
5
],
TEMP
[
6
])
+
K
[
t
]
+
W
[
t
];
int
t2
=
bigSig0
(
TEMP
[
0
])
+
maj
(
TEMP
[
0
],
TEMP
[
1
],
TEMP
[
2
]);
System
.
arraycopy
(
TEMP
,
0
,
TEMP
,
1
,
TEMP
.
length
-
1
);
TEMP
[
4
]
+=
t1
;
TEMP
[
0
]
=
t1
+
t2
;
}
// add values in TEMP to values in H
for
(
int
t
=
0
;
t
<
H
.
length
;
++
t
)
{
H
[
t
]
+=
TEMP
[
t
];
}
}
return
toByteArray
(
H
);
}
/**
* <b>Internal method, no need to call.</b> Pads the given message to have a length
* that is a multiple of 512 bits (64 bytes), including the addition of a
* 1-bit, k 0-bits, and the message length as a 64-bit integer.
* The result is a 32-bit integer array with big-endian byte representation.
*
* @param message The message to pad.
* @return A new array with the padded message bytes.
*/
public
static
int
[]
pad
(
byte
[]
message
)
{
// new message length: original + 1-bit and padding + 8-byte length
// --> block count: whole blocks + (padding + length rounded up)
int
finalBlockLength
=
message
.
length
%
BLOCK_BYTES
;
int
blockCount
=
message
.
length
/
BLOCK_BYTES
+
(
finalBlockLength
+
1
+
8
>
BLOCK_BYTES
?
2
:
1
);
final
IntBuffer
result
=
IntBuffer
.
allocate
(
blockCount
*
(
BLOCK_BYTES
/
Integer
.
BYTES
));
// copy as much of the message as possible
ByteBuffer
buf
=
ByteBuffer
.
wrap
(
message
);
for
(
int
i
=
0
,
n
=
message
.
length
/
Integer
.
BYTES
;
i
<
n
;
++
i
)
{
result
.
put
(
buf
.
getInt
());
}
// copy the remaining bytes (less than 4) and append 1 bit (rest is zero)
ByteBuffer
remainder
=
ByteBuffer
.
allocate
(
4
);
remainder
.
put
(
buf
).
put
((
byte
)
0b10000000
).
rewind
();
result
.
put
(
remainder
.
getInt
());
// ignore however many pad bytes (implicitly calculated in the beginning)
result
.
position
(
result
.
capacity
()
-
2
);
// place original message length as 64-bit integer at the end
long
msgLength
=
message
.
length
*
8L
;
result
.
put
((
int
)
(
msgLength
>>>
32
));
result
.
put
((
int
)
msgLength
);
return
result
.
array
();
}
/**
* Converts the given int array into a byte array via big-endian conversion
* (1 int becomes 4 bytes).
*
* @param ints The source array.
* @return The converted array.
*/
private
static
byte
[]
toByteArray
(
int
[]
ints
)
{
ByteBuffer
buf
=
ByteBuffer
.
allocate
(
ints
.
length
*
Integer
.
BYTES
);
for
(
int
i
:
ints
)
{
buf
.
putInt
(
i
);
}
return
buf
.
array
();
}
private
static
int
ch
(
int
x
,
int
y
,
int
z
)
{
return
(
x
&
y
)
|
((~
x
)
&
z
);
}
private
static
int
maj
(
int
x
,
int
y
,
int
z
)
{
return
(
x
&
y
)
|
(
x
&
z
)
|
(
y
&
z
);
}
private
static
int
bigSig0
(
int
x
)
{
return
Integer
.
rotateRight
(
x
,
2
)
^
Integer
.
rotateRight
(
x
,
13
)
^
Integer
.
rotateRight
(
x
,
22
);
}
private
static
int
bigSig1
(
int
x
)
{
return
Integer
.
rotateRight
(
x
,
6
)
^
Integer
.
rotateRight
(
x
,
11
)
^
Integer
.
rotateRight
(
x
,
25
);
}
private
static
int
smallSig0
(
int
x
)
{
return
Integer
.
rotateRight
(
x
,
7
)
^
Integer
.
rotateRight
(
x
,
18
)
^
(
x
>>>
3
);
}
private
static
int
smallSig1
(
int
x
)
{
return
Integer
.
rotateRight
(
x
,
17
)
^
Integer
.
rotateRight
(
x
,
19
)
^
(
x
>>>
10
);
}
}
jap-http-api/src/main/java/com/fujieid/jap/httpapi/util/DigestUtil.java
0 → 100644
浏览文件 @
624acc9e
package
com.fujieid.jap.httpapi.util
;
import
cn.hutool.core.lang.UUID
;
import
java.util.concurrent.atomic.LongAdder
;
/**
* @author zhihai.yu (mvbbb(a)foxmail.com)
* @version 1.0.0
* @since 1.0.0
*/
public
final
class
DigestUtil
{
private
static
final
LongAdder
LONG_ADDER
=
new
LongAdder
();
public
static
String
getCnonce
(){
return
UUID
.
randomUUID
().
toString
().
replaceAll
(
"-"
,
""
).
substring
(
0
,
16
);
}
public
static
String
getNc
(){
LONG_ADDER
.
increment
();
return
LONG_ADDER
.
toString
();
}
public
static
String
getResponseByQop
(
String
ha1
,
String
nonce
,
String
nc
,
String
cnonce
,
String
qop
,
String
ha2
)
{
if
(
qop
!=
null
&&(
qop
.
contains
(
"auth"
)||
qop
.
contains
(
"auth-init"
))){
return
DigestMD5Util
.
encode
(
ha1
,
nonce
,
nc
,
cnonce
,
qop
,
ha2
);
}
else
{
return
DigestMD5Util
.
encode
(
ha1
,
nonce
,
ha2
);
}
}
public
static
String
getHa2ByQop
(
String
qop
,
String
method
,
String
digestUri
)
{
if
(
qop
==
null
||!
qop
.
contains
(
"auth-init"
)){
return
DigestMD5Util
.
encode
(
method
,
digestUri
);
}
else
{
// TODO Support "auth-init" ha2 compute method
return
null
;
}
}
}
jap-http-api/src/main/java/com/fujieid/jap/httpapi/util/HttpAuthUtil.java
0 → 100644
浏览文件 @
624acc9e
package
com.fujieid.jap.httpapi.util
;
import
com.fujieid.jap.httpapi.enums.HttpMethodEnum
;
import
com.fujieid.jap.httpapi.subject.HttpAuthResponse
;
import
com.xkcoding.http.HttpUtil
;
import
com.xkcoding.http.support.SimpleHttpResponse
;
import
com.xkcoding.http.support.HttpHeader
;
import
com.xkcoding.http.support.SimpleHttpResponse
;
import
java.util.List
;
import
java.util.Map
;
/**
* @author zhihai.yu (mvbbb(a)foxmail.com)
* @version 1.0.0
* @since 1.0.0
*/
public
final
class
HttpAuthUtil
{
public
static
HttpAuthResponse
sendRequest
(
String
url
,
HttpMethodEnum
method
,
Map
<
String
,
String
>
header
,
Map
<
String
,
String
>
params
,
String
body
){
SimpleHttpResponse
response
=
null
;
switch
(
method
){
case
get:
response
=
HttpUtil
.
get
(
url
,
params
,
new
HttpHeader
(
header
),
false
);
break
;
case
post:
if
(
body
==
null
||
""
.
equals
(
body
)){
response
=
HttpUtil
.
post
(
url
,
params
,
new
HttpHeader
(
header
),
false
);
}
else
{
response
=
HttpUtil
.
post
(
url
,
body
,
new
HttpHeader
(
header
));
}
break
;
default
:
break
;
}
if
(
response
==
null
){
return
null
;
}
String
responseBody
=
response
.
getBody
();
Map
<
String
,
List
<
String
>>
headers
=
response
.
getHeaders
();
return
new
HttpAuthResponse
(
response
.
isSuccess
(),
responseBody
,
headers
);
}
}
jap-http-api/src/main/java/com/fujieid/jap/httpapi/util/SimpleAuthJsonUtil.java
0 → 100644
浏览文件 @
624acc9e
package
com.fujieid.jap.httpapi.util
;
import
com.fujieid.jap.core.JapUser
;
import
java.util.Map
;
/**
* Convert between json and auth info
*
* @author zhihai.yu (mvbbb(a)foxmail.com)
* @version 1.0.0
* @since 1.0.0
*/
public
final
class
SimpleAuthJsonUtil
{
public
static
String
getJsonStrByParams
(
Map
<
String
,
String
>
params
){
return
getJsonStrByJapUserAndParams
(
null
,
params
);
}
public
static
String
getJsonStrByJapUserAndParams
(
JapUser
japUser
,
Map
<
String
,
String
>
params
){
if
(
japUser
==
null
&&
params
==
null
){
return
null
;
}
StringBuilder
str
=
new
StringBuilder
();
str
.
append
(
"{"
);
if
(
japUser
!=
null
){
str
.
append
(
"\"username\":\""
).
append
(
japUser
.
getUsername
()).
append
(
"\",\"password:\""
).
append
(
japUser
.
getPassword
()).
append
(
"\","
);
}
if
(
params
!=
null
){
params
.
forEach
((
key
,
value
)
->
str
.
append
(
"\""
).
append
(
key
).
append
(
"\":\""
).
append
(
value
).
append
(
"\","
));
}
if
(
str
.
charAt
(
str
.
length
()-
1
)==
','
){
str
.
deleteCharAt
(
str
.
length
()-
1
);
}
str
.
append
(
"}"
);
return
str
.
toString
();
}
}
jap-http-api/src/main/java/com/fujieid/jap/httpapi/util/SubjectSerializeUtil.java
0 → 100644
浏览文件 @
624acc9e
package
com.fujieid.jap.httpapi.util
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.InvocationTargetException
;
import
java.util.HashMap
;
import
java.util.Objects
;
/**
* used to convert "Authorization Request Header" and "WWW-Authenticate Response Header" between string and object
* @author zhihai.yu (mvbbb(a)foxmail.com)
* @version 1.0.0
* @since 1.0.0
*/
public
final
class
SubjectSerializeUtil
{
/**
* Deserialize string to object
* @param clazz
* @param str
* @return
* @throws NoSuchMethodException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws InstantiationException
*/
public
static
Object
deSerialize
(
Class
<?>
clazz
,
String
str
)
throws
NoSuchMethodException
,
IllegalAccessException
,
InvocationTargetException
,
InstantiationException
{
str
=
str
.
replace
(
"\\"
,
""
).
replace
(
"\""
,
""
).
trim
();
String
[]
split
=
str
.
split
(
","
);
HashMap
<
String
,
String
>
params
=
new
HashMap
<>(
8
);
for
(
String
s
:
split
)
{
String
[]
param
=
s
.
split
(
"="
);
String
paramKey
=
param
[
0
].
trim
();
String
paramValue
=
param
[
1
].
trim
();
params
.
put
(
paramKey
,
paramValue
);
}
Field
[]
fields
=
clazz
.
getDeclaredFields
();
Object
t
=
clazz
.
getDeclaredConstructor
().
newInstance
();
for
(
Field
field
:
fields
)
{
field
.
setAccessible
(
true
);
String
name
=
field
.
getName
();
field
.
set
(
t
,
params
.
get
(
name
));
}
return
t
;
}
/**
* Serialize object to string
* @param t
* @return
* @throws IllegalAccessException
*/
public
static
String
serialize
(
Object
t
)
throws
IllegalAccessException
{
Class
<?>
clazz
=
t
.
getClass
();
StringBuilder
sb
=
new
StringBuilder
();
Field
[]
fields
=
clazz
.
getDeclaredFields
();
boolean
firstParam
=
true
;
for
(
Field
field
:
fields
)
{
field
.
setAccessible
(
true
);
String
paramName
=
field
.
getName
();
String
paramVal
=
((
String
)
field
.
get
(
t
));
if
(
Objects
.
isNull
(
paramVal
)){
continue
;
}
if
(!
firstParam
){
sb
.
append
(
","
);
}
firstParam
=
false
;
sb
.
append
(
paramName
).
append
(
"=\""
).
append
(
paramVal
).
append
(
"\""
);
}
return
sb
.
toString
();
}
}
jap-http-api/src/main/java/com/fujieid/jap/httpapi/util/URLUtil.java
0 → 100644
浏览文件 @
624acc9e
package
com.fujieid.jap.httpapi.util
;
/**
* URLUtil
*
* @author zhihai.yu (mvbbb(a)foxmail.com)
* @version 1.0.0
* @since 1.0.0
*/
public
class
URLUtil
{
private
static
final
String
HTTPS_PREFIX
=
"https://"
;
private
static
final
String
HTTP_PREFIX
=
"http://"
;
/**
* Get relative uri from uri.
* https://www.google.com ==>> www.google.com
* @param uri
* @return
*/
public
static
String
getRelativeUri
(
String
uri
){
if
(
uri
==
null
){
return
null
;
}
String
relativeUri
=
null
;
if
(
uri
.
startsWith
(
HTTPS_PREFIX
)){
relativeUri
=
uri
.
replaceFirst
(
HTTPS_PREFIX
,
""
);
}
else
if
(
uri
.
startsWith
(
HTTP_PREFIX
)){
relativeUri
=
uri
.
replaceFirst
(
HTTP_PREFIX
,
""
);
}
else
{
relativeUri
=
uri
;
}
relativeUri
=
relativeUri
.
substring
(
relativeUri
.
indexOf
(
'/'
));
return
relativeUri
;
}
}
pom.xml
浏览文件 @
624acc9e
...
...
@@ -48,11 +48,12 @@
<module>
jap-mfa
</module>
<module>
jap-ids
</module>
<module>
jap-bom
</module>
<module>
jap-http-api
</module>
</modules>
<properties>
<!-- jap version -->
<revision>
1.0.
5
</revision>
<revision>
1.0.
2
</revision>
<java.version>
1.8
</java.version>
<project.build.sourceEncoding>
UTF-8
</project.build.sourceEncoding>
<!-- maven -->
...
...
@@ -72,13 +73,13 @@
<mockito.version>
2.23.4
</mockito.version>
<hutool.version>
5.5.7
</hutool.version>
<jakarta.servlet.version>
4.0.4
</jakarta.servlet.version>
<justauth.version>
1.16.
2
</justauth.version>
<justauth.version>
1.16.
1
</justauth.version>
<jose4j.version>
0.7.6
</jose4j.version>
<slf4j-api.version>
1.7.30
</slf4j-api.version>
<jedis.version>
3.2.0
</jedis.version>
<kisso.version>
3.7.6
</kisso.version>
<simple-json.version>
0.0.2
</simple-json.version>
<simple-http.version>
1.0.
3
</simple-http.version>
<simple-http.version>
1.0.
4
</simple-http.version>
<zxing.version>
3.3.3
</zxing.version>
<googleauth.version>
1.4.0
</googleauth.version>
<commons-cli.version>
1.4
</commons-cli.version>
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录