Compare commits
80 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
88962ff193 | ||
|
|
fa310c341d | ||
|
|
5624eec331 | ||
|
|
140959c298 | ||
|
|
77f5ff4215 | ||
|
|
38cb811b33 | ||
|
|
c53abe003e | ||
|
|
995e6133d3 | ||
|
|
9858eab556 | ||
|
|
cc2f20dd94 | ||
|
|
2026535275 | ||
|
|
12406980f5 | ||
|
|
44ccfaa1d5 | ||
|
|
d00421ccfd | ||
|
|
c888cec376 | ||
|
|
7c851e1630 | ||
|
|
47c12dd3d9 | ||
|
|
274f7c2df0 | ||
|
|
d4e448f153 | ||
|
|
657f57a5b1 | ||
|
|
618aba8b74 | ||
|
|
49cb4712c9 | ||
|
|
9777edefcc | ||
|
|
f19e2aa6f2 | ||
|
|
d0659bc130 | ||
|
|
ae669d2310 | ||
|
|
889cc23e6f | ||
|
|
bc2fcb7ac5 | ||
|
|
142041d12d | ||
|
|
d48750f24a | ||
|
|
5ccb71e64d | ||
|
|
aad4e7e878 | ||
|
|
3bee9b5896 | ||
|
|
c110fee2b1 | ||
|
|
0f19da93f4 | ||
|
|
69325ee6e5 | ||
|
|
101fd1c70b | ||
|
|
99a4fd879c | ||
|
|
74d96c2d44 | ||
|
|
2ce5c1828b | ||
|
|
6375e38c3d | ||
|
|
9770acf991 | ||
|
|
647d899771 | ||
|
|
d1d8924b60 | ||
|
|
6b7b3cef79 | ||
|
|
22b5632b32 | ||
|
|
d33bbedf40 | ||
|
|
c803c9a854 | ||
|
|
f842006420 | ||
|
|
b009b2489a | ||
|
|
6045df9c5f | ||
|
|
5a5d66b33c | ||
|
|
a708783f87 | ||
|
|
c199b7e1c0 | ||
|
|
0527968490 | ||
|
|
16912f7562 | ||
|
|
2b899bba17 | ||
|
|
7fbee21998 | ||
|
|
7466deea8c | ||
|
|
e1d0091643 | ||
|
|
1e76c26715 | ||
|
|
9b2f949df2 | ||
|
|
4b94c7ff0a | ||
|
|
d7a8a4f771 | ||
|
|
ec13e0af21 | ||
|
|
1a2fd71060 | ||
|
|
68c30a4405 | ||
|
|
3e15322fe1 | ||
|
|
75a1c67aac | ||
|
|
7ad3130371 | ||
|
|
b41fd5c8d2 | ||
|
|
bcacd7e084 | ||
|
|
d885ad9699 | ||
|
|
652083494e | ||
|
|
fbb401a9e0 | ||
|
|
55e883e7bc | ||
|
|
f673161618 | ||
|
|
8707c92924 | ||
|
|
516070c1e4 | ||
|
|
6f93485e2c |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -42,4 +42,7 @@ classpath-data.json
|
||||
/*/.gitignore
|
||||
|
||||
/.gradle/
|
||||
/.gradle/*
|
||||
/.gradle/*
|
||||
/build/
|
||||
setEnvVars.bat
|
||||
/bin/
|
||||
|
||||
@@ -92,7 +92,7 @@ App Management UI
|
||||
Download the current version of Baidu Pan,<a href="https://maxkey.top/zh/about/download.html" target="_blank"> history version</a>
|
||||
| Version | ReleaseDate | Download URL | Code |
|
||||
| --------| :----- | :---- | :----: |
|
||||
| v 2.4.0 RC | 2020/12/15 | <a href="https://pan.baidu.com/s/1xUZZJrxEUmbU3thIxd2lDA" target="_blank">Download</a> | **k65z** |
|
||||
| v 2.6.0 GA | 2021/03/05 | <a href="https://pan.baidu.com/s/1q5hzNeWweu4cpVOO-VopIw" target="_blank">Download</a> | **0x24** |
|
||||
|
||||
|
||||
# Roadmap
|
||||
@@ -101,4 +101,6 @@ Download the current version of Baidu Pan,<a href="https://maxkey.top/zh/about/d
|
||||
|
||||
2. Maxkey-Cloud (micro service version)-2021
|
||||
|
||||
# User Registration
|
||||
|
||||
<a href="https://github.com/MaxKeyTop/MaxKey/issues/40" target="_blank"> Click to register </a> as MaxKey user and contribute to MaxKey!
|
||||
|
||||
@@ -92,7 +92,7 @@ App Management UI
|
||||
Download the current version of Baidu Pan,<a href="https://maxkey.top/zh/about/download.html" target="_blank"> history version</a>
|
||||
| Version | Date | URL | Code |
|
||||
| --------| :----- | :---- | :----: |
|
||||
| v 2.4.0 RC | 2020/12/15 | <a href="https://pan.baidu.com/s/1xUZZJrxEUmbU3thIxd2lDA" target="_blank">Download</a> | **k65z** |
|
||||
| v 2.6.0 GA | 2021/03/05 | <a href="https://pan.baidu.com/s/1q5hzNeWweu4cpVOO-VopIw" target="_blank">Download</a> | **0x24** |
|
||||
|
||||
|
||||
# Roadmap
|
||||
@@ -101,4 +101,7 @@ Download the current version of Baidu Pan,<a href="https://maxkey.top/zh/about/d
|
||||
|
||||
2. Maxkey-Cloud (micro service version)-2021
|
||||
|
||||
# User Registration
|
||||
|
||||
<a href="https://github.com/MaxKeyTop/MaxKey/issues/40" target="_blank"> Click to register </a> as MaxKey user and contribute to MaxKey!
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
# 概述
|
||||
|
||||
<b>MaxKey(马克思的钥匙)</b>单点登录认证系统(Single Sign On System),寓意是最大钥匙,是<b>业界领先的企业级开源IAM身份管理和身份认证产品</b>,支持OAuth 2.0/OpenID Connect、SAML 2.0、JWT、CAS、SCIM等标准协议,提供<b>简单、标准、安全和开放</b>的用户身份管理(IDM)、身份认证(AM)、单点登录(SSO)、RBAC权限管理和资源管理等。
|
||||
<b>MaxKey</b>单点登录认证系统(Single Sign On System),MaxKey中文谐音马克思的钥匙寓意是最大钥匙,是<b>业界领先的企业级开源IAM身份管理和身份认证产品</b>,支持OAuth 2.0/OpenID Connect、SAML 2.0、JWT、CAS、SCIM等标准协议,提供<b>简单、标准、安全和开放</b>的用户身份管理(IDM)、身份认证(AM)、单点登录(SSO)、RBAC权限管理和资源管理等。
|
||||
|
||||
官方网站 <a href="https://www.maxkey.top" target="_blank"><b>官网</b></a> | <a href="https://maxkeytop.gitee.io" target="_blank"><b>官网二线</b></a>
|
||||
|
||||
@@ -94,7 +94,7 @@ QQ交流群:<b>434469201</b>
|
||||
当前版本百度网盘下载,<a href="https://maxkey.top/zh/about/download.html" target="_blank"> 历史版本</a>
|
||||
| 版本 | 日期 | 下载地址 | 提取码 |
|
||||
| --------| :----- | :---- | :----: |
|
||||
| v 2.4.0 RC | 2020/12/15 | <a href="https://pan.baidu.com/s/1xUZZJrxEUmbU3thIxd2lDA" target="_blank">链接下载</a> | **k65z** |
|
||||
| v 2.6.0 GA | 2021/03/05 | <a href="https://pan.baidu.com/s/1q5hzNeWweu4cpVOO-VopIw" target="_blank">链接下载</a> | **0x24** |
|
||||
|
||||
|
||||
# Roadmap
|
||||
@@ -103,4 +103,6 @@ QQ交流群:<b>434469201</b>
|
||||
|
||||
2.MaxKey Cloud(微服务版)-2021年
|
||||
|
||||
# 接入登记
|
||||
|
||||
<a href="https://gitee.com/maxkeytop/MaxKey/issues/I2BNRZ" target="_blank"> 点击进行接入登记</a>,为 MaxKey的发展贡献自己的力量!
|
||||
|
||||
@@ -1,4 +1,71 @@
|
||||
MaxKey v 2.4.0 RC 2020/12/16
|
||||
MaxKey v 2.6.0 GA 2021/03/05
|
||||
*(MAXKEY-210201) 官方网站的优化
|
||||
*(MAXKEY-210202) CAS代理模式实现的优化,完成demo的测试
|
||||
*(MAXKEY-210203) CAS代理模式Demo开发和实现
|
||||
*(MAXKEY-210204) LINUX版安装指南优化,升级MySQL到8.0
|
||||
*(MAXKEY-210205) 构建优化,实现自动打包到Build Release
|
||||
*(MAXKEY-210206) springboot-actuator优化
|
||||
*(MAXKEY-210207) 登录模式的拆分和整合
|
||||
*(MAXKEY-210208) 模块的重组和优化,拆分出通用模块maxkey-common,captcha,otp,social等
|
||||
*(MAXKEY-210209) REST API优化,增加密码修改功能
|
||||
*(MAXKEY-210210) session及cookie参数的优化
|
||||
*(MAXKEY-210211) kafka供应服务移动到org.maxkey.persistence.kafka
|
||||
*(MAXKEY-210212) 用户注册功能优化
|
||||
*(MAXKEY-210213) 日志信息输出优化
|
||||
*(MAXKEY-210214) 简化MaxKey banner输出
|
||||
*(MAXKEY-210215) token工厂模式的实现Factorys
|
||||
*(MAXKEY-210216) OTP的优化
|
||||
*(MAXKEY-210217) MapperScan重复优化
|
||||
*(MAXKEY-210218) maxkey-mgt端口号调整9527,wiki端口号调整9521
|
||||
*(MAXKEY-210219) 依赖jar引用、更新和升级
|
||||
spring 5.3.4
|
||||
springBoot 2.4.3
|
||||
springSecurity 5.4.5
|
||||
tomcat 9.0.41
|
||||
freemarker 2.3.31
|
||||
kafka-clients 2.6.1
|
||||
spring-kafka 2.6.6
|
||||
micrometer 1.6.4
|
||||
latencyutils 2.0.3
|
||||
stax2-api 4.2.1
|
||||
druid 1.2.5
|
||||
|
||||
|
||||
MaxKey v 2.5.0 GA 2021/02/05
|
||||
*(MAXKEY-210101) 动态用户组实现优化,增加时间段控制
|
||||
*(MAXKEY-210102) 官方网站优化,取消加载动态图表;增加统计功能
|
||||
*(MAXKEY-210103) 优化社交登录的图标
|
||||
*(MAXKEY-210104) 社交账号支持Gitee和微信
|
||||
*(MAXKEY-210105) 社交账号绑定列表化,显示绑定时间和最近登录时间,绑定的操作,支持多个OAuth第三方,参见JustAuth
|
||||
*(MAXKEY-210106) 语言选择位置调整
|
||||
*(MAXKEY-210107) 短信验证码存储Redis修复
|
||||
*(MAXKEY-210108) OAuthDetail修复Visible
|
||||
*(MAXKEY-210109) 镜像加速gradle默认使用阿里云aliyun
|
||||
*(MAXKEY-210110) Swagger文档支持 maxkey/swagger-ui/index.html#/
|
||||
*(MAXKEY-210111) knife4j文档支持 maxkey/doc.html
|
||||
*(MAXKEY-210112) 登录界面加密处理
|
||||
*(MAXKEY-210113) 依赖jar引用、更新和升级
|
||||
spring 5.3.3
|
||||
springBoot 2.4.2
|
||||
jedis 3.4.1
|
||||
druid 1.2.4
|
||||
JustAuth 1.15.9
|
||||
joda-time 2.10.9
|
||||
zxing 3.4.1
|
||||
jackson 2.12.1
|
||||
guava 30.1-jre
|
||||
mybatis 3.5.6
|
||||
mybatis-spring 2.0.6
|
||||
hibernate 6.2.0.Final
|
||||
jibGradlePlugin 2.7.0
|
||||
nimbus-jose-jwt 9.4.1
|
||||
tomcat-embed-core 9.0.41
|
||||
swagger 1.6.2
|
||||
swagger3 2.1.6
|
||||
springfox 3.0.0
|
||||
knife4j 3.0.2
|
||||
|
||||
MaxKey v 2.4.0 GA 2021/01/01
|
||||
*(MAXKEY-201001) 动态用户组实现(基于用户属性或机构)
|
||||
*(MAXKEY-201002) 任职机构和兼职机构
|
||||
*(MAXKEY-201003) 登录会话切换的优化
|
||||
|
||||
203
build.gradle
203
build.gradle
@@ -1,5 +1,21 @@
|
||||
/*
|
||||
* This build file was auto generated by running the Gradle buildrelease.bat
|
||||
* Copyright [2021] [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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MaxKey build file was auto generated by running the Gradle release.bat
|
||||
*/
|
||||
|
||||
defaultTasks "clean", "build"
|
||||
@@ -32,11 +48,11 @@ allprojects {
|
||||
|
||||
eclipse {
|
||||
/*第一次时请注释这段eclipse设置,可能报错*/
|
||||
// jdt {
|
||||
// File f = file('.settings/org.eclipse.core.resources.prefs')
|
||||
// f.write('eclipse.preferences.version=1\n')
|
||||
// f.append('encoding/<project>=UTF-8') //use UTF-8
|
||||
// }
|
||||
jdt {
|
||||
File f = file('.settings/org.eclipse.core.resources.prefs')
|
||||
f.write('eclipse.preferences.version=1\n')
|
||||
f.append('encoding/<project>=UTF-8') //use UTF-8
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@@ -91,19 +107,20 @@ subprojects {
|
||||
}
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
maven { url "https://repo1.maven.org/maven2/" }
|
||||
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/'}
|
||||
maven { url "https://repo.spring.io/plugins-release/" }
|
||||
maven { url "https://repo.spring.io/milestone" }
|
||||
maven { url "https://repo1.maven.org/maven2/" }
|
||||
maven { url "https://build.shibboleth.net/nexus/content/repositories/releases/" }
|
||||
maven { url "https://mvnrepository.com/repos/central/" }
|
||||
maven { url "https://mvnrepository.com/repos/central/" }
|
||||
maven { url "http://jcenter.bintray.com" }
|
||||
maven { url "http://mvn.gt.igexin.com/nexus/content/repositories/releases"}
|
||||
maven { url "https://plugins.gradle.org/m2/" }
|
||||
maven { url "https://repo.spring.io/plugins-release/" }
|
||||
maven { url "https://repo.spring.io/milestone" }
|
||||
maven { url "https://oss.sonatype.org/content/repositories/releases/" }
|
||||
maven { url "https://maven.repository.redhat.com/ga/" }
|
||||
maven { url "https://repository.apache.org/content/repositories/releases/" }
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
//all dependencies
|
||||
@@ -140,14 +157,14 @@ subprojects {
|
||||
compile group: 'org.apache.httpcomponents', name: 'httpcore', version: '4.4.13'
|
||||
compile group: 'org.apache.velocity', name: 'velocity', version: '1.7'
|
||||
compile group: 'velocity', name: 'velocity-dep', version: '1.4'
|
||||
compile group: 'org.freemarker', name: 'freemarker', version: '2.3.30'
|
||||
compile group: 'org.freemarker', name: 'freemarker', version: '2.3.31'
|
||||
compile group: 'org.apache.xmlbeans', name: 'xmlbeans', version: '3.0.1'
|
||||
compile group: 'org.apache.commons', name: 'commons-compress', version: '1.20'
|
||||
compile group: 'org.apache.poi', name: 'poi', version: "${poiVersion}"
|
||||
compile group: 'org.apache.poi', name: 'poi-ooxml', version: "${poiVersion}"
|
||||
compile group: 'org.apache.poi', name: 'poi-ooxml-schemas', version: "${poiVersion}"
|
||||
compile group: 'org.apache.poi', name: 'poi-scratchpad', version: "${poiVersion}"
|
||||
compile group: 'org.apache.commons', name: 'not-yet-commons-ssl', version: '0.3.9'
|
||||
//compile group: 'org.apache.commons', name: 'not-yet-commons-ssl', version: '0.3.9'
|
||||
|
||||
//logs
|
||||
compile group: 'org.apache.logging.log4j', name: 'log4j-1.2-api', version: "${log4jVersion}"
|
||||
@@ -184,9 +201,9 @@ subprojects {
|
||||
|
||||
//kafka support
|
||||
// https://mvnrepository.com/artifact/org.apache.kafka/kafka-clients
|
||||
compile group: 'org.apache.kafka', name: 'kafka-clients', version: '2.5.0'
|
||||
compile group: 'org.apache.kafka', name: 'kafka-clients', version: '2.6.1'
|
||||
// https://mvnrepository.com/artifact/org.springframework.kafka/spring-kafka
|
||||
compile group: 'org.springframework.kafka', name: 'spring-kafka', version: '2.5.2.RELEASE'
|
||||
compile group: 'org.springframework.kafka', name: 'spring-kafka', version: '2.6.6'
|
||||
// https://mvnrepository.com/artifact/org.springframework.retry/spring-retry
|
||||
compile group: 'org.springframework.retry', name: 'spring-retry', version: '1.3.0'
|
||||
|
||||
@@ -198,6 +215,8 @@ subprojects {
|
||||
compile group: 'org.springframework.boot', name: 'spring-boot', version: "${springBootVersion}"
|
||||
compile group: 'org.springframework.boot', name: 'spring-boot-starter', version: "${springBootVersion}"
|
||||
compile group: 'org.springframework.boot', name: 'spring-boot-actuator', version: "${springBootVersion}"
|
||||
compile group: 'org.springframework.boot', name: 'spring-boot-starter-actuator', version: "${springBootVersion}"
|
||||
compile group: 'org.springframework.boot', name: 'spring-boot-actuator-autoconfigure', version: "${springBootVersion}"
|
||||
compile group: 'org.springframework.boot', name: 'spring-boot-autoconfigure', version: "${springBootVersion}"
|
||||
compile group: 'org.springframework.boot', name: 'spring-boot-starter-freemarker', version: "${springBootVersion}"
|
||||
compile group: 'org.springframework.boot', name: 'spring-boot-starter-log4j2', version: "${springBootVersion}"
|
||||
@@ -212,19 +231,23 @@ subprojects {
|
||||
//spring-session
|
||||
compile group: 'org.springframework.session', name: 'spring-session-core', version: "${springSessionVersion}"
|
||||
compile group: 'org.springframework.session', name: 'spring-session-data-redis', version: "${springSessionVersion}"
|
||||
|
||||
compile group: 'org.springframework.plugin', name: 'spring-plugin-core', version: '2.0.0.RELEASE'
|
||||
compile group: 'org.springframework.plugin', name: 'spring-plugin-metadata', version: '2.0.0.RELEASE'
|
||||
|
||||
//saml
|
||||
compile group: 'org.opensaml', name: 'opensaml', version: '2.6.6'
|
||||
compile group: 'org.opensaml', name: 'openws', version: '1.5.6'
|
||||
compile group: 'org.opensaml', name: 'xmltooling', version: '1.4.6'
|
||||
compile group: 'net.shibboleth.utilities', name: 'java-support', version: '7.5.1'
|
||||
//jose-jwt
|
||||
compile group: 'com.nimbusds', name: 'nimbus-jose-jwt', version: '9.0.1'
|
||||
compile group: 'com.nimbusds', name: 'nimbus-jose-jwt', version: '9.4.1'
|
||||
compile group: 'net.jcip', name: 'jcip-annotations', version: '1.0'
|
||||
compile group: 'net.minidev', name: 'json-smart', version: '2.3'
|
||||
compile group: 'net.minidev', name: 'asm', version: '1.0.2'
|
||||
//oauth third party JustAuth
|
||||
compile group: 'com.xkcoding.http', name: 'simple-http', version: '1.0.3'
|
||||
compile group: 'me.zhyd.oauth', name: 'JustAuth', version: '1.15.8'
|
||||
compile group: 'me.zhyd.oauth', name: 'JustAuth', version: '1.15.9'
|
||||
//common
|
||||
compile group: 'org.javassist', name: 'javassist', version: '3.23.0-GA'
|
||||
compile group: 'org.owasp.esapi', name: 'esapi', version: '2.2.0.0'
|
||||
@@ -255,6 +278,10 @@ subprojects {
|
||||
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "${jacksonVersion}"
|
||||
compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: "${jacksonVersion}"
|
||||
compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: "${jacksonVersion}"
|
||||
compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: "${jacksonVersion}"
|
||||
compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: "${jacksonVersion}"
|
||||
compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: "${jacksonVersion}"
|
||||
|
||||
compile group: 'com.fasterxml', name: 'classmate', version: '1.5.0'
|
||||
compile group: 'com.alibaba', name: 'fastjson', version: '1.2.74'
|
||||
//reactive
|
||||
@@ -265,24 +292,24 @@ subprojects {
|
||||
compile group: 'org.quartz-scheduler', name: 'quartz', version: '2.3.2'
|
||||
//database
|
||||
compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.21'
|
||||
compile group: 'com.alibaba', name: 'druid', version: '1.2.1'
|
||||
compile group: 'com.alibaba', name: 'druid-spring-boot-starter', version: '1.2.1'
|
||||
compile group: 'redis.clients', name: 'jedis', version: '3.3.0'
|
||||
compile group: 'com.alibaba', name: 'druid', version: '1.2.5'
|
||||
compile group: 'com.alibaba', name: 'druid-spring-boot-starter', version: '1.2.5'
|
||||
compile group: 'redis.clients', name: 'jedis', version: '3.4.1'
|
||||
compile group: 'org.ehcache', name: 'ehcache', version: '3.9.0'
|
||||
//mybatis
|
||||
compile group: 'org.mybatis', name: 'mybatis', version: '3.5.5'
|
||||
compile group: 'org.mybatis', name: 'mybatis-spring', version: '2.0.5'
|
||||
compile group: 'org.mybatis', name: 'mybatis', version: '3.5.6'
|
||||
compile group: 'org.mybatis', name: 'mybatis-spring', version: '2.0.6'
|
||||
//hibernate
|
||||
compile group: 'org.hibernate.validator', name: 'hibernate-validator', version: "${hibernateVersion}"
|
||||
compile group: 'org.hibernate', name: 'hibernate-validator-cdi', version: "${hibernateVersion}"
|
||||
compile group: 'org.hibernate.validator', name: 'hibernate-validator-annotation-processor', version: "${hibernateVersion}"
|
||||
//usefull
|
||||
compile group: 'joda-time', name: 'joda-time', version: '2.10.6'
|
||||
compile group: 'joda-time', name: 'joda-time', version: '2.10.9'
|
||||
compile group: 'org.yaml', name: 'snakeyaml', version: '1.26'
|
||||
compile group: 'net.sourceforge.nekohtml', name: 'nekohtml', version: '1.9.22'
|
||||
compile group: 'org.jdom', name: 'jdom', version: '2.0.2'
|
||||
compile group: 'com.google.zxing', name: 'core', version: '3.4.0'
|
||||
compile group: 'com.google.guava', name: 'guava', version: '29.0-jre'
|
||||
compile group: 'com.google.zxing', name: 'core', version: '3.4.1'
|
||||
compile group: 'com.google.guava', name: 'guava', version: '30.1-jre'
|
||||
compile group: 'ognl', name: 'ognl', version: '3.2.14'
|
||||
compile group: 'cglib', name: 'cglib', version: '3.3.0'
|
||||
compile group: 'org.ow2.asm', name: 'asm', version: '7.3.1'
|
||||
@@ -295,7 +322,41 @@ subprojects {
|
||||
compile group: 'org.ogce', name: 'xpp3', version: '1.1.6'
|
||||
compile group: 'com.thoughtworks.xstream', name: 'xstream', version: '1.4.10'
|
||||
compile group: 'org.passay', name: 'passay', version: '1.6.0'
|
||||
|
||||
compile group: 'io.micrometer', name: 'micrometer-core', version: '1.6.4'
|
||||
compile group: 'org.latencyutils', name: 'LatencyUtils', version: '2.0.3'
|
||||
compile group: 'org.codehaus.woodstox', name: 'stax2-api', version: '4.2.1'
|
||||
|
||||
//docs
|
||||
compile group: 'org.mapstruct', name: 'mapstruct', version: '1.4.1.Final'
|
||||
compile group: 'io.swagger', name: 'swagger-annotations', version: "${swaggerVersion}"
|
||||
compile group: 'io.swagger', name: 'swagger-models', version: "${swaggerVersion}"
|
||||
compile group: 'io.swagger.core.v3', name: 'swagger-annotations', version: "${swaggerV3Version}"
|
||||
compile group: 'io.swagger.core.v3', name: 'swagger-core', version: "${swaggerV3Version}"
|
||||
compile group: 'io.swagger.core.v3', name: 'swagger-integration', version: "${swaggerV3Version}"
|
||||
compile group: 'io.swagger.core.v3', name: 'swagger-models', version: "${swaggerV3Version}"
|
||||
//springfox
|
||||
compile group: 'io.springfox', name: 'springfox-bean-validators', version: "${springfoxVersion}"
|
||||
compile group: 'io.springfox', name: 'springfox-core', version: "${springfoxVersion}"
|
||||
compile group: 'io.springfox', name: 'springfox-data-rest', version: "${springfoxVersion}"
|
||||
compile group: 'io.springfox', name: 'springfox-spi', version: "${springfoxVersion}"
|
||||
compile group: 'io.springfox', name: 'springfox-oas', version: "${springfoxVersion}"
|
||||
compile group: 'io.springfox', name: 'springfox-schema', version: "${springfoxVersion}"
|
||||
compile group: 'io.springfox', name: 'springfox-swagger2', version: "${springfoxVersion}"
|
||||
compile group: 'io.springfox', name: 'springfox-swagger-ui', version: "${springfoxVersion}"
|
||||
compile group: 'io.springfox', name: 'springfox-swagger-common', version: "${springfoxVersion}"
|
||||
compile group: 'io.springfox', name: 'springfox-spring-webmvc', version: "${springfoxVersion}"
|
||||
compile group: 'io.springfox', name: 'springfox-spring-web', version: "${springfoxVersion}"
|
||||
compile group: 'io.springfox', name: 'springfox-spring-webflux', version: "${springfoxVersion}"
|
||||
compile group: 'io.springfox', name: 'springfox-boot-starter', version: "${springfoxVersion}"
|
||||
//knife4j
|
||||
compile group: 'com.github.xiaoymin', name: 'knife4j-annotations', version: "${knife4jVersion}"
|
||||
compile group: 'com.github.xiaoymin', name: 'knife4j-core', version: "${knife4jVersion}"
|
||||
compile group: 'com.github.xiaoymin', name: 'knife4j-spring-mvc', version: "${knife4jVersion}"
|
||||
compile group: 'com.github.xiaoymin', name: 'knife4j-spring', version: "${knife4jVersion}"
|
||||
compile group: 'com.github.xiaoymin', name: 'knife4j-spring-ui', version: "${knife4jVersion}"
|
||||
compile group: 'com.github.xiaoymin', name: 'knife4j-spring-boot-starter', version: "${knife4jVersion}"
|
||||
compile group: 'com.github.xiaoymin', name: 'knife4j-spring-boot-autoconfigure', version: "${knife4jVersion}"
|
||||
|
||||
//local jars
|
||||
compile fileTree(dir: "${rootDir}/maxkey-lib/", include: '*.jar')
|
||||
//阿里云
|
||||
@@ -304,7 +365,7 @@ subprojects {
|
||||
compile group: 'com.tencentcloudapi', name: 'tencentcloud-sdk-java', version: '3.1.33'
|
||||
|
||||
//tomcat embed Core Tomcat implementation
|
||||
compile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '9.0.38'
|
||||
compile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '9.0.43'
|
||||
//JULI logging implementation for embedded Tomcat
|
||||
compile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-logging-juli', version: '8.5.2'
|
||||
}
|
||||
@@ -330,40 +391,80 @@ subprojects {
|
||||
include '*.jar'
|
||||
}
|
||||
|
||||
task copydemoWar2Release(type: Copy) {
|
||||
into "$rootDir/build/demowar/"
|
||||
from "$buildDir/libs/"
|
||||
include '*demo*.war'
|
||||
}
|
||||
|
||||
task copyWar2Release(type: Copy) {
|
||||
into "$rootDir/build/maxkey-war"
|
||||
from "$buildDir/libs/"
|
||||
include '*web*.war'
|
||||
}
|
||||
|
||||
task copyotherWar2Release(type: Copy) {
|
||||
into "$rootDir/build/"
|
||||
from "$buildDir/libs/"
|
||||
}
|
||||
|
||||
task buildRelease(dependsOn:['build','jar','copyjar2Release']) {
|
||||
//项目名
|
||||
println "project " + project.name + " environment ..."
|
||||
}
|
||||
}
|
||||
|
||||
//copy Dep Jars to /build/maxkey-depjars
|
||||
project('maxkey-core') {
|
||||
//copy Dep Jars to /build/maxkey-depjars,only maxkey-common deps
|
||||
project('maxkey-common') {
|
||||
task copyDepJars(type: Copy){
|
||||
println "copy Dep Jars to $rootDir/build/maxkey-depjars"
|
||||
def paths = ["$rootDir/build/MaxKey-v${project.version}GA",
|
||||
"$rootDir/build/MaxKey-v${project.version}GA/maxkey",
|
||||
"$rootDir/build/MaxKey-v${project.version}GA/maxkey_mgt",
|
||||
"$rootDir/build/MaxKey-v${project.version}GA/maxkey_lib"];
|
||||
//遍历数组,调用createDir闭包,创建目录
|
||||
|
||||
paths.forEach(){path->
|
||||
File dir=new File(path);
|
||||
if (!dir.exists()){
|
||||
print("create "+path+"\n")
|
||||
dir.mkdirs();
|
||||
}
|
||||
};
|
||||
|
||||
println "copy Dep Jars to $rootDir/build/MaxKey-v${project.version}GA/maxkey_lib"
|
||||
|
||||
from configurations.runtime
|
||||
into "$rootDir/build/maxkey-depjars"
|
||||
into "$rootDir/build/MaxKey-v${project.version}GA/maxkey_lib";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
task copyMaxKey(type: Copy) {
|
||||
from "$rootDir/build/maxkey-jars/maxkey-authentication-social-${project.version}.jar"
|
||||
from "$rootDir/build/maxkey-jars/maxkey-web-maxkey-${project.version}.jar"
|
||||
into "$rootDir/build/MaxKey-v${project.version}GA/maxkey/";
|
||||
}
|
||||
|
||||
task copyMaxKeyMgt(type: Copy) {
|
||||
from "$rootDir/build/maxkey-jars/maxkey-identity-rest-${project.version}.jar"
|
||||
from "$rootDir/build/maxkey-jars/maxkey-identity-scim-${project.version}.jar"
|
||||
from "$rootDir/build/maxkey-jars/maxkey-web-manage-${project.version}.jar"
|
||||
into "$rootDir/build/MaxKey-v${project.version}GA/maxkey_mgt/";
|
||||
}
|
||||
|
||||
task copyMaxKeyLibs(type: Copy) {
|
||||
from "$rootDir/build/maxkey-jars/maxkey-authentication-otp-${project.version}.jar"
|
||||
from "$rootDir/build/maxkey-jars/maxkey-authentication-captcha-${project.version}.jar"
|
||||
from "$rootDir/build/maxkey-jars/maxkey-authentication-core-${project.version}.jar"
|
||||
from "$rootDir/build/maxkey-jars/maxkey-common-${project.version}.jar"
|
||||
from "$rootDir/build/maxkey-jars/maxkey-core-${project.version}.jar"
|
||||
from "$rootDir/build/maxkey-jars/maxkey-persistence-${project.version}.jar"
|
||||
from "$rootDir/build/maxkey-jars/maxkey-protocol-authorize-${project.version}.jar"
|
||||
from "$rootDir/build/maxkey-jars/maxkey-protocol-cas-${project.version}.jar"
|
||||
from "$rootDir/build/maxkey-jars/maxkey-protocol-desktop-${project.version}.jar"
|
||||
from "$rootDir/build/maxkey-jars/maxkey-protocol-extendapi-${project.version}.jar"
|
||||
from "$rootDir/build/maxkey-jars/maxkey-protocol-formbased-${project.version}.jar"
|
||||
from "$rootDir/build/maxkey-jars/maxkey-protocol-jwt-${project.version}.jar"
|
||||
from "$rootDir/build/maxkey-jars/maxkey-protocol-oauth-2.0-${project.version}.jar"
|
||||
from "$rootDir/build/maxkey-jars/maxkey-protocol-saml-2.0-${project.version}.jar"
|
||||
from "$rootDir/build/maxkey-jars/maxkey-protocol-tokenbased-${project.version}.jar"
|
||||
into "$rootDir/build/MaxKey-v${project.version}GA/maxkey_lib";
|
||||
}
|
||||
|
||||
task copyMaxKeyShellScript(type: Copy) {
|
||||
from "$rootDir/shellscript"
|
||||
into "$rootDir/build/MaxKey-v${project.version}GA/";
|
||||
}
|
||||
|
||||
|
||||
task buildReleaseCopy(dependsOn:['copyMaxKey','copyMaxKeyMgt','copyMaxKeyLibs','copyMaxKeyShellScript']) {
|
||||
//项目名
|
||||
println "project ReleaseCopy ."
|
||||
|
||||
}
|
||||
|
||||
task buildRelease(dependsOn:['build']) {
|
||||
//项目名
|
||||
println "project " + project.name + " environment ..."
|
||||
@@ -376,7 +477,9 @@ task buildRelease(dependsOn:['build']) {
|
||||
//项目的build文件绝对路径
|
||||
println "project buildDir " + project.buildDir
|
||||
println 'Build MaxKey '+project.name +' '
|
||||
|
||||
}
|
||||
|
||||
// In this section you declare the dependencies for your production and test code
|
||||
dependencies {
|
||||
|
||||
|
||||
@@ -1,18 +1,24 @@
|
||||
#maxkey properties
|
||||
group =maxkey.top
|
||||
version =2.4.0
|
||||
version =2.6.0
|
||||
vendor =https://www.maxkey.top
|
||||
author =maxkeyTop
|
||||
|
||||
#Version For use jar
|
||||
log4jVersion =2.14.0
|
||||
springVersion =5.3.2
|
||||
springBootVersion =2.4.1
|
||||
springSecurityVersion =5.4.2
|
||||
springVersion =5.3.4
|
||||
springBootVersion =2.4.3
|
||||
springSecurityVersion =5.4.5
|
||||
springDataVersion =2.4.1
|
||||
springSessionVersion =2.4.1
|
||||
hibernateVersion =6.1.5.Final
|
||||
hibernateVersion =6.2.0.Final
|
||||
slf4jVersion =1.7.30
|
||||
jacksonVersion =2.11.2
|
||||
jacksonVersion =2.12.1
|
||||
bouncycastleVersion =1.64
|
||||
httpcomponentsVersion =4.5.12
|
||||
poiVersion =4.1.2
|
||||
jibGradlePluginVersion =2.6.0
|
||||
jibGradlePluginVersion =2.7.0
|
||||
swaggerVersion =1.6.2
|
||||
swaggerV3Version =2.1.6
|
||||
springfoxVersion =3.0.0
|
||||
knife4jVersion =3.0.2
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 38 KiB |
@@ -1,16 +0,0 @@
|
||||
|
||||
description = "maxkey-authentications"
|
||||
|
||||
|
||||
dependencies {
|
||||
//local jars
|
||||
compile fileTree(dir: '../maxkey-lib/', include: '*/*.jar')
|
||||
|
||||
|
||||
|
||||
compile project(":maxkey-core")
|
||||
compile project(":maxkey-persistence")
|
||||
compile project(":maxkey-protocols:maxkey-protocol-oauth-2.0")
|
||||
compile project(":maxkey-protocols:maxkey-protocol-saml-2.0")
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
description = "maxkey-authentication-captcha"
|
||||
|
||||
|
||||
dependencies {
|
||||
//local jars
|
||||
compile fileTree(dir: '../maxkey-lib/', include: '*/*.jar')
|
||||
|
||||
compile project(":maxkey-common")
|
||||
compile project(":maxkey-core")
|
||||
compile project(":maxkey-persistence")
|
||||
|
||||
}
|
||||
@@ -15,13 +15,14 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.web.image;
|
||||
package org.maxkey.web.contorller;
|
||||
|
||||
import com.google.code.kaptcha.Producer;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.maxkey.web.WebConstants;
|
||||
import org.maxkey.web.image.AbstractImageEndpoint;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
description = "maxkey-authentication-core"
|
||||
|
||||
|
||||
dependencies {
|
||||
//local jars
|
||||
compile fileTree(dir: '../maxkey-lib/', include: '*/*.jar')
|
||||
|
||||
compile project(":maxkey-common")
|
||||
compile project(":maxkey-core")
|
||||
compile project(":maxkey-persistence")
|
||||
compile project(":maxkey-authentications:maxkey-authentication-otp")
|
||||
|
||||
}
|
||||
@@ -26,14 +26,12 @@ import org.maxkey.authn.support.rememberme.AbstractRemeberMeService;
|
||||
import org.maxkey.configuration.ApplicationConfig;
|
||||
import org.maxkey.constants.ConstantsLoginType;
|
||||
import org.maxkey.crypto.password.PasswordReciprocal;
|
||||
import org.maxkey.crypto.password.opt.AbstractOptAuthn;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.password.onetimepwd.AbstractOtpAuthn;
|
||||
import org.maxkey.web.WebConstants;
|
||||
import org.maxkey.web.WebContext;
|
||||
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.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
@@ -50,24 +48,14 @@ public abstract class AbstractAuthenticationProvider {
|
||||
private static final Logger _logger =
|
||||
LoggerFactory.getLogger(AbstractAuthenticationProvider.class);
|
||||
|
||||
@Autowired
|
||||
@Qualifier("applicationConfig")
|
||||
protected ApplicationConfig applicationConfig;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("authenticationRealm")
|
||||
protected AbstractAuthenticationRealm authenticationRealm;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("tfaOptAuthn")
|
||||
protected AbstractOptAuthn tfaOptAuthn;
|
||||
protected AbstractOtpAuthn tfaOtpAuthn;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("remeberMeService")
|
||||
protected AbstractRemeberMeService remeberMeService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("onlineTicketServices")
|
||||
protected OnlineTicketServices onlineTicketServices;
|
||||
|
||||
public static ArrayList<GrantedAuthority> grantedAdministratorsAuthoritys = new ArrayList<GrantedAuthority>();
|
||||
@@ -239,7 +227,7 @@ public abstract class AbstractAuthenticationProvider {
|
||||
validUserInfo.setSharedSecret(sharedSecret);
|
||||
validUserInfo.setSharedCounter(userInfo.getSharedCounter());
|
||||
validUserInfo.setId(userInfo.getId());
|
||||
if (otpCaptcha == null || !tfaOptAuthn.validate(validUserInfo, otpCaptcha)) {
|
||||
if (otpCaptcha == null || !tfaOtpAuthn.validate(validUserInfo, otpCaptcha)) {
|
||||
String message = WebContext.getI18nValue("login.error.captcha");
|
||||
_logger.debug("login captcha valid error.");
|
||||
throw new BadCredentialsException(message);
|
||||
@@ -332,8 +320,8 @@ public abstract class AbstractAuthenticationProvider {
|
||||
this.authenticationRealm = authenticationRealm;
|
||||
}
|
||||
|
||||
public void setTfaOptAuthn(AbstractOptAuthn tfaOptAuthn) {
|
||||
this.tfaOptAuthn = tfaOptAuthn;
|
||||
public void setTfaOtpAuthn(AbstractOtpAuthn tfaOtpAuthn) {
|
||||
this.tfaOtpAuthn = tfaOtpAuthn;
|
||||
}
|
||||
|
||||
public void setRemeberMeService(AbstractRemeberMeService remeberMeService) {
|
||||
@@ -20,7 +20,12 @@ package org.maxkey.authn;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.maxkey.authn.online.OnlineTicket;
|
||||
import org.maxkey.authn.online.OnlineTicketServices;
|
||||
import org.maxkey.authn.realm.AbstractAuthenticationRealm;
|
||||
import org.maxkey.authn.support.rememberme.AbstractRemeberMeService;
|
||||
import org.maxkey.configuration.ApplicationConfig;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.password.onetimepwd.AbstractOtpAuthn;
|
||||
import org.maxkey.web.WebConstants;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
@@ -46,8 +51,27 @@ public class RealmAuthenticationProvider extends AbstractAuthenticationProvider
|
||||
protected String getProviderName() {
|
||||
return "RealmAuthenticationProvider";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RealmAuthenticationProvider() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
public RealmAuthenticationProvider(
|
||||
AbstractAuthenticationRealm authenticationRealm,
|
||||
ApplicationConfig applicationConfig,
|
||||
AbstractOtpAuthn tfaOtpAuthn,
|
||||
AbstractRemeberMeService remeberMeService,
|
||||
OnlineTicketServices onlineTicketServices) {
|
||||
this.authenticationRealm = authenticationRealm;
|
||||
this.applicationConfig = applicationConfig;
|
||||
this.tfaOtpAuthn = tfaOtpAuthn;
|
||||
this.remeberMeService = remeberMeService;
|
||||
this.onlineTicketServices = onlineTicketServices;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Authentication doInternalAuthenticate(LoginCredential loginCredential) {
|
||||
|
||||
_logger.debug("authentication " + loginCredential);
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.maxkey.authn.online;
|
||||
|
||||
import org.maxkey.constants.ConstantsPersistence;
|
||||
import org.maxkey.persistence.redis.RedisConnectionFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
public class OnlineTicketServicesFactory {
|
||||
private static final Logger _logger =
|
||||
LoggerFactory.getLogger(OnlineTicketServicesFactory.class);
|
||||
|
||||
public OnlineTicketServices getService(
|
||||
int persistence,
|
||||
JdbcTemplate jdbcTemplate,
|
||||
RedisConnectionFactory redisConnFactory){
|
||||
|
||||
OnlineTicketServices onlineTicketServices = null;
|
||||
if (persistence == ConstantsPersistence.INMEMORY) {
|
||||
onlineTicketServices = new InMemoryOnlineTicketServices();
|
||||
_logger.debug("InMemoryOnlineTicketServices");
|
||||
} else if (persistence == ConstantsPersistence.JDBC) {
|
||||
_logger.debug("OnlineTicketServices not support ");
|
||||
} else if (persistence == ConstantsPersistence.REDIS) {
|
||||
onlineTicketServices = new RedisOnlineTicketServices(redisConnFactory);
|
||||
_logger.debug("RedisOnlineTicketServices");
|
||||
}
|
||||
|
||||
return onlineTicketServices;
|
||||
}
|
||||
}
|
||||
@@ -32,8 +32,6 @@ import org.maxkey.web.WebConstants;
|
||||
import org.maxkey.web.WebContext;
|
||||
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.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
|
||||
@@ -49,17 +47,12 @@ public abstract class AbstractAuthenticationRealm {
|
||||
|
||||
protected boolean provisioning;
|
||||
|
||||
@Autowired
|
||||
protected PasswordPolicyValidator passwordPolicyValidator;
|
||||
|
||||
@Autowired
|
||||
protected LoginService loginService;
|
||||
|
||||
@Autowired
|
||||
|
||||
protected LoginHistoryService loginHistoryService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("remeberMeService")
|
||||
protected AbstractRemeberMeService remeberMeService;
|
||||
|
||||
/**
|
||||
@@ -24,7 +24,6 @@ import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
@@ -38,8 +37,8 @@ import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
public class DefaultJdbcAuthenticationRealm extends AbstractAuthenticationRealm {
|
||||
private static Logger _logger = LoggerFactory.getLogger(DefaultJdbcAuthenticationRealm.class);
|
||||
|
||||
@Autowired
|
||||
private PasswordEncoder passwordEncoder;
|
||||
|
||||
protected PasswordEncoder passwordEncoder;
|
||||
|
||||
public DefaultJdbcAuthenticationRealm() {
|
||||
|
||||
@@ -17,9 +17,14 @@
|
||||
|
||||
package org.maxkey.authn.realm.jdbc;
|
||||
|
||||
import org.maxkey.authn.support.rememberme.AbstractRemeberMeService;
|
||||
import org.maxkey.persistence.db.LoginHistoryService;
|
||||
import org.maxkey.persistence.db.LoginService;
|
||||
import org.maxkey.persistence.db.PasswordPolicyValidator;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
/**
|
||||
* JdbcAuthenticationRealm.
|
||||
@@ -36,5 +41,23 @@ public class JdbcAuthenticationRealm extends DefaultJdbcAuthenticationRealm {
|
||||
public JdbcAuthenticationRealm(JdbcTemplate jdbcTemplate) {
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
}
|
||||
|
||||
public JdbcAuthenticationRealm(
|
||||
PasswordEncoder passwordEncoder,
|
||||
PasswordPolicyValidator passwordPolicyValidator,
|
||||
LoginService loginService,
|
||||
LoginHistoryService loginHistoryService,
|
||||
AbstractRemeberMeService remeberMeService,
|
||||
JdbcTemplate jdbcTemplate) {
|
||||
|
||||
this.passwordEncoder =passwordEncoder;
|
||||
this.passwordPolicyValidator=passwordPolicyValidator;
|
||||
this.loginService = loginService;
|
||||
this.loginHistoryService = loginHistoryService;
|
||||
this.remeberMeService = remeberMeService;
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.maxkey.authn.AbstractAuthenticationProvider;
|
||||
import org.maxkey.constants.ConstantsLoginType;
|
||||
import org.maxkey.util.AuthorizationHeaderCredential;
|
||||
import org.maxkey.util.AuthorizationHeaderUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -78,8 +79,6 @@ public class BasicEntryPoint implements AsyncHandlerInterceptor {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// session not exists,session timeout,recreate new session
|
||||
if(request.getSession(false) == null) {
|
||||
_logger.info("recreate new session .");
|
||||
@@ -95,20 +94,19 @@ public class BasicEntryPoint implements AsyncHandlerInterceptor {
|
||||
_logger.info("Authentication fail header Authorization is null . ");
|
||||
return false;
|
||||
}
|
||||
String username=null;
|
||||
String password=null;
|
||||
|
||||
AuthorizationHeaderCredential headerCredential = null;
|
||||
|
||||
if(AuthorizationHeaderUtils.isBasic(basicCredential)){
|
||||
String []usernamePassword=AuthorizationHeaderUtils.resolveBasic(basicCredential);
|
||||
username=usernamePassword[0];
|
||||
password=usernamePassword[1];
|
||||
headerCredential=AuthorizationHeaderUtils.resolve(basicCredential);
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
if(username==null||username.equals("")){
|
||||
if(headerCredential.getUsername()==null||headerCredential.getUsername().equals("")){
|
||||
_logger.info("Authentication fail username is null . ");
|
||||
return false;
|
||||
}
|
||||
if(password==null||password.equals("")){
|
||||
if(headerCredential.getCredential()==null||headerCredential.getCredential().equals("")){
|
||||
_logger.info("Authentication fail password is null . ");
|
||||
return false;
|
||||
}
|
||||
@@ -123,7 +121,7 @@ public class BasicEntryPoint implements AsyncHandlerInterceptor {
|
||||
UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
||||
String lastSessionUserName = authenticationToken.getPrincipal().toString();
|
||||
_logger.info("Authentication Principal : " + lastSessionUserName);
|
||||
if (lastSessionUserName != null && !lastSessionUserName.equals(username)) {
|
||||
if (lastSessionUserName != null && !lastSessionUserName.equals(headerCredential.getUsername())) {
|
||||
isAuthenticated=false;
|
||||
}else{
|
||||
isAuthenticated=true;
|
||||
@@ -131,8 +129,8 @@ public class BasicEntryPoint implements AsyncHandlerInterceptor {
|
||||
}
|
||||
|
||||
if(!isAuthenticated){
|
||||
authenticationProvider.trustAuthentication(username,ConstantsLoginType.BASIC,"","","success");
|
||||
_logger.info("Authentication "+username+" successful .");
|
||||
authenticationProvider.trustAuthentication(headerCredential.getUsername(),ConstantsLoginType.BASIC,"","","success");
|
||||
_logger.info("Authentication "+headerCredential.getUsername()+" successful .");
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -0,0 +1,81 @@
|
||||
package org.maxkey.authn.support.certs;
|
||||
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.maxkey.authn.AbstractAuthenticationProvider;
|
||||
import org.maxkey.authn.support.httpheader.HttpHeaderEntryPoint;
|
||||
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.web.servlet.AsyncHandlerInterceptor;
|
||||
|
||||
public class HttpCertsEntryPoint implements AsyncHandlerInterceptor {
|
||||
private static final Logger _logger = LoggerFactory.getLogger(HttpHeaderEntryPoint.class);
|
||||
|
||||
static String CERTIFICATE_ATTRIBUTE = "javax.servlet.request.X509Certificate";
|
||||
static String PEER_CERTIFICATES_ATTRIBUTE = "javax.net.ssl.peer_certificates";
|
||||
|
||||
boolean enable;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("authenticationProvider")
|
||||
AbstractAuthenticationProvider authenticationProvider ;
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
|
||||
|
||||
if(!enable){
|
||||
return true;
|
||||
}
|
||||
|
||||
_logger.debug("Certificate Login Start ...");
|
||||
_logger.debug("Request url : "+ request.getRequestURL());
|
||||
_logger.debug("Request URI : "+ request.getRequestURI());
|
||||
_logger.trace("Request ContextPath : "+ request.getContextPath());
|
||||
_logger.trace("Request ServletPath : "+ request.getServletPath());
|
||||
_logger.trace("RequestSessionId : "+ request.getRequestedSessionId());
|
||||
_logger.trace("isRequestedSessionIdValid : "+ request.isRequestedSessionIdValid());
|
||||
_logger.trace("getSession : "+ request.getSession(false));
|
||||
|
||||
X509Certificate[] certificates= (X509Certificate[])request.getAttribute(CERTIFICATE_ATTRIBUTE); // 2.2 spec
|
||||
if (certificates == null) {
|
||||
certificates = (X509Certificate[]) request.getAttribute(PEER_CERTIFICATES_ATTRIBUTE); // 2.1 spec
|
||||
}
|
||||
|
||||
for (X509Certificate cert : certificates) {
|
||||
cert.checkValidity();
|
||||
_logger.debug("cert validated");
|
||||
_logger.debug("cert infos " + cert.toString());
|
||||
_logger.debug("Version " + cert.getVersion());
|
||||
_logger.debug("SerialNumber " + cert.getSerialNumber().toString(16));
|
||||
_logger.debug("SubjectDN " + cert.getSubjectDN());
|
||||
_logger.debug("IssuerDN " + cert.getIssuerDN());
|
||||
_logger.debug("NotBefore " + cert.getNotBefore());
|
||||
_logger.debug("SigAlgName " + cert.getSigAlgName());
|
||||
byte[] sign = cert.getSignature();
|
||||
_logger.debug("Signature ");
|
||||
for (int j = 0; j < sign.length; j++){
|
||||
_logger.debug(sign[j] + ",");
|
||||
}
|
||||
java.security.PublicKey pk = cert.getPublicKey();
|
||||
byte[] pkenc = pk.getEncoded();
|
||||
_logger.debug("PublicKey ");
|
||||
for (int j = 0; j < pkenc.length; j++){
|
||||
_logger.debug(pkenc[j] + ",");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public HttpCertsEntryPoint(boolean enable, AbstractAuthenticationProvider authenticationProvider) {
|
||||
super();
|
||||
this.enable = enable;
|
||||
this.authenticationProvider = authenticationProvider;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -54,18 +54,18 @@ public class HttpHeaderEntryPoint implements AsyncHandlerInterceptor {
|
||||
return true;
|
||||
}
|
||||
String requestPath=request.getServletPath();
|
||||
_logger.debug("HttpHeader Login Start ...");
|
||||
_logger.info("Request url : "+ request.getRequestURL());
|
||||
_logger.info("Request URI : "+ request.getRequestURI());
|
||||
_logger.info("Request ContextPath : "+ request.getContextPath());
|
||||
_logger.info("Request ServletPath : "+ request.getServletPath());
|
||||
_logger.debug("RequestSessionId : "+ request.getRequestedSessionId());
|
||||
_logger.debug("isRequestedSessionIdValid : "+ request.isRequestedSessionIdValid());
|
||||
_logger.debug("getSession : "+ request.getSession(false));
|
||||
_logger.trace("HttpHeader Login Start ...");
|
||||
_logger.trace("Request url : "+ request.getRequestURL());
|
||||
_logger.trace("Request URI : "+ request.getRequestURI());
|
||||
_logger.trace("Request ContextPath : "+ request.getContextPath());
|
||||
_logger.trace("Request ServletPath : "+ request.getServletPath());
|
||||
_logger.trace("RequestSessionId : "+ request.getRequestedSessionId());
|
||||
_logger.trace("isRequestedSessionIdValid : "+ request.isRequestedSessionIdValid());
|
||||
_logger.trace("getSession : "+ request.getSession(false));
|
||||
|
||||
for(int i=0;i<skipRequestURI.length;i++){
|
||||
if(skipRequestURI[i].indexOf(requestPath)>-1){
|
||||
_logger.info("skip uri : "+ requestPath);
|
||||
_logger.trace("skip uri : "+ requestPath);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -74,14 +74,14 @@ public class HttpHeaderEntryPoint implements AsyncHandlerInterceptor {
|
||||
|
||||
// session not exists,session timeout,recreate new session
|
||||
if(request.getSession(false) == null) {
|
||||
_logger.info("recreate new session .");
|
||||
_logger.trace("recreate new session .");
|
||||
request.getSession(true);
|
||||
}
|
||||
|
||||
_logger.info("getSession.getId : "+ request.getSession().getId());
|
||||
_logger.trace("getSession.getId : "+ request.getSession().getId());
|
||||
String httpHeaderUsername = request.getHeader(headerName);
|
||||
|
||||
_logger.info("HttpHeader username : " + httpHeaderUsername);
|
||||
_logger.trace("HttpHeader username : " + httpHeaderUsername);
|
||||
|
||||
|
||||
if(httpHeaderUsername==null||httpHeaderUsername.equals("")){
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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.authn.support.jwt;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.maxkey.authn.AbstractAuthenticationProvider;
|
||||
import org.maxkey.configuration.ApplicationConfig;
|
||||
import org.maxkey.constants.ConstantsLoginType;
|
||||
import org.maxkey.web.WebConstants;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.servlet.AsyncHandlerInterceptor;
|
||||
|
||||
import com.nimbusds.jwt.SignedJWT;
|
||||
|
||||
|
||||
public class HttpJwtEntryPoint implements AsyncHandlerInterceptor {
|
||||
private static final Logger _logger = LoggerFactory.getLogger(HttpJwtEntryPoint.class);
|
||||
|
||||
boolean enable;
|
||||
|
||||
ApplicationConfig applicationConfig;
|
||||
|
||||
AbstractAuthenticationProvider authenticationProvider ;
|
||||
|
||||
JwtLoginService jwtLoginService;
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
|
||||
boolean isAuthenticated= WebContext.isAuthenticated();
|
||||
String jwt = request.getParameter(WebConstants.JWT_TOKEN_PARAMETER);
|
||||
|
||||
if(!enable
|
||||
|| isAuthenticated
|
||||
|| jwt == null){
|
||||
return true;
|
||||
}
|
||||
|
||||
_logger.debug("JWT Login Start ...");
|
||||
_logger.trace("Request url : "+ request.getRequestURL());
|
||||
_logger.trace("Request URI : "+ request.getRequestURI());
|
||||
_logger.trace("Request ContextPath : "+ request.getContextPath());
|
||||
_logger.trace("Request ServletPath : "+ request.getServletPath());
|
||||
_logger.trace("RequestSessionId : "+ request.getRequestedSessionId());
|
||||
_logger.trace("isRequestedSessionIdValid : "+ request.isRequestedSessionIdValid());
|
||||
_logger.trace("getSession : "+ request.getSession(false));
|
||||
|
||||
// session not exists,session timeout,recreate new session
|
||||
if(request.getSession(false) == null) {
|
||||
_logger.trace("recreate new session .");
|
||||
request.getSession(true);
|
||||
}
|
||||
|
||||
_logger.trace("getSession.getId : "+ request.getSession().getId());
|
||||
|
||||
//for jwt Login
|
||||
_logger.debug("jwt : " + jwt);
|
||||
|
||||
SignedJWT signedJWT = jwtLoginService.jwtTokenValidation(jwt);
|
||||
if(signedJWT != null) {
|
||||
String username =signedJWT.getJWTClaimsSet().getSubject();
|
||||
authenticationProvider.trustAuthentication(username, ConstantsLoginType.JWT, "", "", "success");
|
||||
_logger.debug("JWT Logined in , username " + username);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public HttpJwtEntryPoint() {
|
||||
super();
|
||||
}
|
||||
|
||||
public HttpJwtEntryPoint (boolean enable) {
|
||||
super();
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
public HttpJwtEntryPoint(AbstractAuthenticationProvider authenticationProvider, JwtLoginService jwtLoginService,
|
||||
ApplicationConfig applicationConfig, boolean enable) {
|
||||
super();
|
||||
this.authenticationProvider = authenticationProvider;
|
||||
this.jwtLoginService = jwtLoginService;
|
||||
this.applicationConfig = applicationConfig;
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
public boolean isEnable() {
|
||||
return enable;
|
||||
}
|
||||
|
||||
public void setEnable(boolean enable) {
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
public void setApplicationConfig(ApplicationConfig applicationConfig) {
|
||||
this.applicationConfig = applicationConfig;
|
||||
}
|
||||
|
||||
public void setAuthenticationProvider(AbstractAuthenticationProvider authenticationProvider) {
|
||||
this.authenticationProvider = authenticationProvider;
|
||||
}
|
||||
|
||||
public void setJwtLoginService(JwtLoginService jwtLoginService) {
|
||||
this.jwtLoginService = jwtLoginService;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,11 +28,8 @@ import com.nimbusds.jwt.PlainJWT;
|
||||
import com.nimbusds.jwt.SignedJWT;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.joda.time.DateTime;
|
||||
import org.maxkey.authn.AbstractAuthenticationProvider;
|
||||
import org.maxkey.configuration.oidc.OIDCProviderMetadataDetails;
|
||||
import org.maxkey.constants.ConstantsLoginType;
|
||||
import org.maxkey.crypto.jwt.signer.service.impl.DefaultJwtSigningAndValidationService;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
@@ -47,77 +44,14 @@ public class JwtLoginService {
|
||||
|
||||
DefaultJwtSigningAndValidationService jwtSignerValidationService;
|
||||
|
||||
AbstractAuthenticationProvider authenticationProvider ;
|
||||
|
||||
|
||||
public JwtLoginService(AbstractAuthenticationProvider authenticationProvider,
|
||||
public JwtLoginService(
|
||||
OIDCProviderMetadataDetails jwtProviderMetadata,
|
||||
DefaultJwtSigningAndValidationService jwtSignerValidationService
|
||||
) {
|
||||
this.authenticationProvider = authenticationProvider;
|
||||
this.jwtProviderMetadata = jwtProviderMetadata;
|
||||
this.jwtSignerValidationService = jwtSignerValidationService;
|
||||
|
||||
}
|
||||
public boolean login(String jwt, HttpServletResponse response) {
|
||||
_logger.debug("jwt : " + jwt);
|
||||
|
||||
String username = null;
|
||||
SignedJWT signedJWT = null;
|
||||
|
||||
boolean loginResult = false;
|
||||
JWTClaimsSet jwtClaimsSet = null;
|
||||
try {
|
||||
|
||||
RSASSAVerifier rsaSSAVerifier = new RSASSAVerifier(((RSAKey) jwtSignerValidationService.getAllPublicKeys()
|
||||
.get(jwtSignerValidationService.getDefaultSignerKeyId())).toRSAPublicKey());
|
||||
|
||||
signedJWT = SignedJWT.parse(jwt);
|
||||
if (signedJWT.verify(rsaSSAVerifier)) {
|
||||
loginResult = true;
|
||||
} else {
|
||||
_logger.debug("verify false ");
|
||||
return false;
|
||||
}
|
||||
jwtClaimsSet = signedJWT.getJWTClaimsSet();
|
||||
|
||||
_logger.debug("" + signedJWT.getPayload());
|
||||
_logger.debug("jwtClaimsSet Issuer " + jwtClaimsSet.getIssuer());
|
||||
_logger.debug("Metadata Issuer " + jwtProviderMetadata.getIssuer());
|
||||
|
||||
if (loginResult && jwtClaimsSet.getIssuer().equals(jwtProviderMetadata.getIssuer())) {
|
||||
loginResult = true;
|
||||
_logger.debug("Issuer equals ");
|
||||
} else {
|
||||
_logger.debug("Issuer not equals ");
|
||||
return false;
|
||||
}
|
||||
|
||||
_logger.debug("username " + jwtClaimsSet.getSubject());
|
||||
|
||||
if (loginResult && jwtClaimsSet.getSubject() != null) {
|
||||
username = jwtClaimsSet.getSubject();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
DateTime now = new DateTime();
|
||||
|
||||
if (loginResult && now.isBefore(jwtClaimsSet.getExpirationTime().getTime())) {
|
||||
authenticationProvider.trustAuthentication(username, ConstantsLoginType.JWT, "", "", "success");
|
||||
return true;
|
||||
}
|
||||
} catch (java.text.ParseException e) {
|
||||
// Invalid signed JWT encoding
|
||||
_logger.error("Invalid signed JWT encoding ");
|
||||
} catch (JOSEException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
_logger.error("JOSEException ");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public String buildLoginJwt() {
|
||||
_logger.debug("buildLoginJwt .");
|
||||
@@ -144,10 +78,8 @@ public class JwtLoginService {
|
||||
return tokenString;
|
||||
}
|
||||
|
||||
public boolean jwtTokenValidation(String jwt) {
|
||||
public SignedJWT jwtTokenValidation(String jwt) {
|
||||
SignedJWT signedJWT = null;
|
||||
|
||||
boolean loginResult = false;
|
||||
JWTClaimsSet jwtClaimsSet = null;
|
||||
try {
|
||||
|
||||
@@ -156,44 +88,34 @@ public class JwtLoginService {
|
||||
|
||||
signedJWT = SignedJWT.parse(jwt);
|
||||
if (signedJWT.verify(rsaSSAVerifier)) {
|
||||
loginResult = true;
|
||||
jwtClaimsSet = signedJWT.getJWTClaimsSet();
|
||||
_logger.debug("" + signedJWT.getPayload());
|
||||
_logger.debug("username " + jwtClaimsSet.getSubject());
|
||||
_logger.debug("jwtClaimsSet Issuer " + jwtClaimsSet.getIssuer());
|
||||
_logger.debug("Metadata Issuer " + jwtProviderMetadata.getIssuer());
|
||||
if ( jwtClaimsSet.getIssuer().equals(jwtProviderMetadata.getIssuer())) {
|
||||
_logger.debug("Issuer equals ");
|
||||
DateTime now = new DateTime();
|
||||
if (now.isBefore(jwtClaimsSet.getExpirationTime().getTime())) {
|
||||
_logger.debug("ExpirationTime Validation " + now.isBefore(jwtClaimsSet.getExpirationTime().getTime()));
|
||||
return signedJWT;
|
||||
}
|
||||
} else {
|
||||
_logger.debug("Issuer not equals ");
|
||||
}
|
||||
} else {
|
||||
_logger.debug("verify false ");
|
||||
}
|
||||
jwtClaimsSet = signedJWT.getJWTClaimsSet();
|
||||
|
||||
_logger.debug("" + signedJWT.getPayload());
|
||||
|
||||
_logger.debug("username " + jwtClaimsSet.getSubject());
|
||||
|
||||
_logger.debug("jwtClaimsSet Issuer " + jwtClaimsSet.getIssuer());
|
||||
_logger.debug("Metadata Issuer " + jwtProviderMetadata.getIssuer());
|
||||
|
||||
if (loginResult && jwtClaimsSet.getIssuer().equals(jwtProviderMetadata.getIssuer())) {
|
||||
loginResult = true;
|
||||
_logger.debug("Issuer equals ");
|
||||
} else {
|
||||
_logger.debug("Issuer not equals ");
|
||||
return false;
|
||||
}
|
||||
|
||||
DateTime now = new DateTime();
|
||||
|
||||
if (loginResult && now.isBefore(jwtClaimsSet.getExpirationTime().getTime())) {
|
||||
_logger.debug("ExpirationTime Validation " + now.isBefore(jwtClaimsSet.getExpirationTime().getTime()));
|
||||
loginResult = true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
} catch (java.text.ParseException e) {
|
||||
// Invalid signed JWT encoding
|
||||
_logger.debug("Invalid signed JWT encoding ");
|
||||
_logger.error("Invalid signed JWT encoding ",e);
|
||||
} catch (JOSEException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
_logger.debug("JOSEException ");
|
||||
_logger.error("JOSEException ",e);
|
||||
}
|
||||
return loginResult;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -205,8 +127,13 @@ public class JwtLoginService {
|
||||
this.jwtSignerValidationService = jwtSignerValidationService;
|
||||
}
|
||||
|
||||
public void setAuthenticationProvider(AbstractAuthenticationProvider authenticationProvider) {
|
||||
this.authenticationProvider = authenticationProvider;
|
||||
}
|
||||
public OIDCProviderMetadataDetails getJwtProviderMetadata() {
|
||||
return jwtProviderMetadata;
|
||||
}
|
||||
public DefaultJwtSigningAndValidationService getJwtSignerValidationService() {
|
||||
return jwtSignerValidationService;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* 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.authn.support.kerberos;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.joda.time.DateTime;
|
||||
import org.maxkey.authn.AbstractAuthenticationProvider;
|
||||
import org.maxkey.configuration.ApplicationConfig;
|
||||
import org.maxkey.constants.ConstantsLoginType;
|
||||
import org.maxkey.crypto.ReciprocalUtils;
|
||||
import org.maxkey.util.DateUtils;
|
||||
import org.maxkey.util.JsonUtils;
|
||||
import org.maxkey.web.WebConstants;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.servlet.AsyncHandlerInterceptor;
|
||||
|
||||
|
||||
public class HttpKerberosEntryPoint implements AsyncHandlerInterceptor {
|
||||
private static final Logger _logger = LoggerFactory.getLogger(HttpKerberosEntryPoint.class);
|
||||
|
||||
boolean enable;
|
||||
|
||||
ApplicationConfig applicationConfig;
|
||||
|
||||
AbstractAuthenticationProvider authenticationProvider ;
|
||||
|
||||
KerberosService kerberosService;
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
|
||||
boolean isAuthenticated= WebContext.isAuthenticated();
|
||||
String kerberosTokenString = request.getParameter(WebConstants.KERBEROS_TOKEN_PARAMETER);
|
||||
String kerberosUserDomain = request.getParameter(WebConstants.KERBEROS_USERDOMAIN_PARAMETER);
|
||||
|
||||
if(!enable
|
||||
|| isAuthenticated
|
||||
|| kerberosTokenString == null){
|
||||
return true;
|
||||
}
|
||||
|
||||
_logger.trace("Kerberos Login Start ...");
|
||||
_logger.trace("Request url : "+ request.getRequestURL());
|
||||
_logger.trace("Request URI : "+ request.getRequestURI());
|
||||
_logger.trace("Request ContextPath : "+ request.getContextPath());
|
||||
_logger.trace("Request ServletPath : "+ request.getServletPath());
|
||||
_logger.trace("RequestSessionId : "+ request.getRequestedSessionId());
|
||||
_logger.trace("isRequestedSessionIdValid : "+ request.isRequestedSessionIdValid());
|
||||
_logger.trace("getSession : "+ request.getSession(false));
|
||||
|
||||
// session not exists,session timeout,recreate new session
|
||||
if(request.getSession(false) == null) {
|
||||
_logger.trace("recreate new session .");
|
||||
request.getSession(true);
|
||||
}
|
||||
|
||||
_logger.trace("getSession.getId : "+ request.getSession().getId());
|
||||
|
||||
//for Kerberos Login
|
||||
_logger.debug("Try Kerberos login ");
|
||||
_logger.debug("encoder Kerberos Token "+kerberosTokenString);
|
||||
_logger.debug("kerberos UserDomain "+kerberosUserDomain);
|
||||
|
||||
String decoderKerberosToken=null;
|
||||
for(KerberosProxy kerberosProxy : kerberosService.getKerberosProxys()){
|
||||
if(kerberosProxy.getUserdomain().equalsIgnoreCase(kerberosUserDomain)){
|
||||
decoderKerberosToken=ReciprocalUtils.aesDecoder(kerberosTokenString, kerberosProxy.getCrypto());
|
||||
break;
|
||||
}
|
||||
}
|
||||
_logger.debug("decoder Kerberos Token "+decoderKerberosToken);
|
||||
KerberosToken kerberosToken=new KerberosToken();
|
||||
kerberosToken=(KerberosToken)JsonUtils.json2Object(decoderKerberosToken, kerberosToken);
|
||||
_logger.debug("Kerberos Token "+kerberosToken);
|
||||
|
||||
DateTime notOnOrAfter=DateUtils.toUtcDate(kerberosToken.getNotOnOrAfter());
|
||||
_logger.debug("Kerberos Token is After Now "+notOnOrAfter.isAfterNow());
|
||||
|
||||
if(notOnOrAfter.isAfterNow()){
|
||||
authenticationProvider.trustAuthentication(kerberosToken.getPrincipal(),ConstantsLoginType.KERBEROS,kerberosUserDomain,"","success");
|
||||
_logger.debug("Kerberos Logined in , username " + kerberosToken.getPrincipal());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public HttpKerberosEntryPoint() {
|
||||
super();
|
||||
}
|
||||
|
||||
public HttpKerberosEntryPoint (boolean enable) {
|
||||
super();
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
public HttpKerberosEntryPoint(AbstractAuthenticationProvider authenticationProvider, KerberosService kerberosService,
|
||||
ApplicationConfig applicationConfig, boolean enable) {
|
||||
super();
|
||||
this.authenticationProvider = authenticationProvider;
|
||||
this.kerberosService = kerberosService;
|
||||
this.applicationConfig = applicationConfig;
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
public boolean isEnable() {
|
||||
return enable;
|
||||
}
|
||||
|
||||
public void setEnable(boolean enable) {
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
public void setApplicationConfig(ApplicationConfig applicationConfig) {
|
||||
this.applicationConfig = applicationConfig;
|
||||
}
|
||||
|
||||
public void setAuthenticationProvider(AbstractAuthenticationProvider authenticationProvider) {
|
||||
this.authenticationProvider = authenticationProvider;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -17,9 +17,11 @@
|
||||
|
||||
package org.maxkey.authn.support.kerberos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface KerberosService {
|
||||
|
||||
public boolean login(String kerberosTokenString,String kerberosUserDomain);
|
||||
public List<KerberosProxy> getKerberosProxys();
|
||||
|
||||
public String buildKerberosProxys( );
|
||||
|
||||
@@ -21,12 +21,6 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.maxkey.authn.AbstractAuthenticationProvider;
|
||||
import org.maxkey.constants.ConstantsLoginType;
|
||||
import org.maxkey.crypto.ReciprocalUtils;
|
||||
import org.maxkey.util.DateUtils;
|
||||
import org.maxkey.util.JsonUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -34,36 +28,6 @@ import org.slf4j.LoggerFactory;
|
||||
public class RemoteKerberosService implements KerberosService{
|
||||
private static Logger _logger = LoggerFactory.getLogger(RemoteKerberosService.class);
|
||||
List<KerberosProxy> kerberosProxys;
|
||||
|
||||
AbstractAuthenticationProvider authenticationProvider ;
|
||||
|
||||
public boolean login(String kerberosTokenString,String kerberosUserDomain){
|
||||
_logger.debug("encoder Kerberos Token "+kerberosTokenString);
|
||||
_logger.debug("kerberos UserDomain "+kerberosUserDomain);
|
||||
|
||||
String decoderKerberosToken=null;
|
||||
for(KerberosProxy kerberosProxy : kerberosProxys){
|
||||
if(kerberosProxy.getUserdomain().equalsIgnoreCase(kerberosUserDomain)){
|
||||
decoderKerberosToken=ReciprocalUtils.aesDecoder(kerberosTokenString, kerberosProxy.getCrypto());
|
||||
break;
|
||||
}
|
||||
}
|
||||
_logger.debug("decoder Kerberos Token "+decoderKerberosToken);
|
||||
KerberosToken kerberosToken=new KerberosToken();
|
||||
kerberosToken=(KerberosToken)JsonUtils.json2Object(decoderKerberosToken, kerberosToken);
|
||||
_logger.debug("Kerberos Token "+kerberosToken);
|
||||
|
||||
DateTime notOnOrAfter=DateUtils.toUtcDate(kerberosToken.getNotOnOrAfter());
|
||||
_logger.debug("Kerberos Token is After Now "+notOnOrAfter.isAfterNow());
|
||||
if(notOnOrAfter.isAfterNow()){
|
||||
authenticationProvider.trustAuthentication(kerberosToken.getPrincipal(),ConstantsLoginType.KERBEROS,kerberosUserDomain,"","success");
|
||||
return true;
|
||||
}else{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<KerberosProxy> getKerberosProxys() {
|
||||
return kerberosProxys;
|
||||
@@ -22,10 +22,7 @@ import java.util.regex.Pattern;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.joda.time.DateTime;
|
||||
import org.maxkey.authn.AbstractAuthenticationProvider;
|
||||
import org.maxkey.configuration.ApplicationConfig;
|
||||
import org.maxkey.constants.ConstantsLoginType;
|
||||
import org.maxkey.constants.ConstantsTimeInterval;
|
||||
import org.maxkey.crypto.Base64Utils;
|
||||
import org.maxkey.crypto.ReciprocalUtils;
|
||||
@@ -47,10 +44,6 @@ public abstract class AbstractRemeberMeService {
|
||||
@Autowired
|
||||
@Qualifier("applicationConfig")
|
||||
protected ApplicationConfig applicationConfig;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("authenticationProvider")
|
||||
AbstractAuthenticationProvider authenticationProvider ;
|
||||
|
||||
// follow function is for persist
|
||||
public abstract void save(RemeberMe remeberMe);
|
||||
@@ -97,38 +90,6 @@ public abstract class AbstractRemeberMeService {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean login(String remeberMe, HttpServletResponse response) {
|
||||
_logger.debug("RemeberMe : " + remeberMe);
|
||||
|
||||
remeberMe = new String(Base64Utils.base64UrlDecode(remeberMe));
|
||||
|
||||
remeberMe = ReciprocalUtils.decoder(remeberMe);
|
||||
|
||||
_logger.debug("decoder RemeberMe : " + remeberMe);
|
||||
RemeberMe remeberMeCookie = new RemeberMe();
|
||||
remeberMeCookie = (RemeberMe) JsonUtils.json2Object(remeberMe, remeberMeCookie);
|
||||
_logger.debug("Remeber Me Cookie : " + remeberMeCookie);
|
||||
|
||||
RemeberMe storeRemeberMe = read(remeberMeCookie);
|
||||
if (storeRemeberMe == null) {
|
||||
return false;
|
||||
}
|
||||
DateTime loginDate = new DateTime(storeRemeberMe.getLastLogin());
|
||||
DateTime expiryDate = loginDate.plusSeconds(getRemeberMeValidity());
|
||||
DateTime now = new DateTime();
|
||||
if (now.isBefore(expiryDate)) {
|
||||
authenticationProvider.trustAuthentication(
|
||||
storeRemeberMe.getUsername(),
|
||||
ConstantsLoginType.REMEBER_ME,
|
||||
"",
|
||||
"",
|
||||
"success");
|
||||
return updateRemeberMe(remeberMeCookie, response);
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean updateRemeberMe(RemeberMe remeberMe, HttpServletResponse response) {
|
||||
remeberMe.setAuthKey(WebContext.genId());
|
||||
remeberMe.setLastLogin(new Date());
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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.authn.support.rememberme;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.maxkey.authn.AbstractAuthenticationProvider;
|
||||
import org.maxkey.configuration.ApplicationConfig;
|
||||
import org.maxkey.constants.ConstantsLoginType;
|
||||
import org.maxkey.crypto.Base64Utils;
|
||||
import org.maxkey.crypto.ReciprocalUtils;
|
||||
import org.maxkey.util.JsonUtils;
|
||||
import org.maxkey.web.WebConstants;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.servlet.AsyncHandlerInterceptor;
|
||||
|
||||
|
||||
public class HttpRemeberMeEntryPoint implements AsyncHandlerInterceptor {
|
||||
private static final Logger _logger = LoggerFactory.getLogger(HttpRemeberMeEntryPoint.class);
|
||||
|
||||
boolean enable;
|
||||
|
||||
ApplicationConfig applicationConfig;
|
||||
|
||||
AbstractAuthenticationProvider authenticationProvider ;
|
||||
|
||||
AbstractRemeberMeService remeberMeService;
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
|
||||
boolean isAuthenticated= WebContext.isAuthenticated();
|
||||
Cookie readRemeberMeCookie = WebContext.readCookieByName(request,WebConstants.REMEBER_ME_COOKIE);
|
||||
|
||||
if(!enable
|
||||
|| isAuthenticated
|
||||
|| readRemeberMeCookie==null
|
||||
|| !applicationConfig.getLoginConfig().isRemeberMe()){
|
||||
return true;
|
||||
}
|
||||
|
||||
_logger.trace("RemeberMe Login Start ...");
|
||||
_logger.trace("Request url : "+ request.getRequestURL());
|
||||
_logger.trace("Request URI : "+ request.getRequestURI());
|
||||
_logger.trace("Request ContextPath : "+ request.getContextPath());
|
||||
_logger.trace("Request ServletPath : "+ request.getServletPath());
|
||||
_logger.trace("RequestSessionId : "+ request.getRequestedSessionId());
|
||||
_logger.trace("isRequestedSessionIdValid : "+ request.isRequestedSessionIdValid());
|
||||
_logger.trace("getSession : "+ request.getSession(false));
|
||||
|
||||
// session not exists,session timeout,recreate new session
|
||||
if(request.getSession(false) == null) {
|
||||
_logger.info("recreate new session .");
|
||||
request.getSession(true);
|
||||
}
|
||||
|
||||
_logger.trace("getSession.getId : "+ request.getSession().getId());
|
||||
|
||||
_logger.debug("Try RemeberMe login ");
|
||||
String remeberMe = readRemeberMeCookie.getValue();
|
||||
_logger.debug("RemeberMe : " + remeberMe);
|
||||
|
||||
remeberMe = new String(Base64Utils.base64UrlDecode(remeberMe));
|
||||
|
||||
remeberMe = ReciprocalUtils.decoder(remeberMe);
|
||||
|
||||
_logger.debug("decoder RemeberMe : " + remeberMe);
|
||||
RemeberMe remeberMeCookie = new RemeberMe();
|
||||
remeberMeCookie = (RemeberMe) JsonUtils.json2Object(remeberMe, remeberMeCookie);
|
||||
_logger.debug("Remeber Me Cookie : " + remeberMeCookie);
|
||||
|
||||
RemeberMe storeRemeberMe = remeberMeService.read(remeberMeCookie);
|
||||
if (storeRemeberMe != null) {
|
||||
DateTime loginDate = new DateTime(storeRemeberMe.getLastLogin());
|
||||
DateTime expiryDate = loginDate.plusSeconds(remeberMeService.getRemeberMeValidity());
|
||||
DateTime now = new DateTime();
|
||||
if (now.isBefore(expiryDate)) {
|
||||
authenticationProvider.trustAuthentication(
|
||||
storeRemeberMe.getUsername(),
|
||||
ConstantsLoginType.REMEBER_ME,
|
||||
"",
|
||||
"",
|
||||
"success");
|
||||
remeberMeService.updateRemeberMe(remeberMeCookie, response);
|
||||
_logger.debug("RemeberMe Logined in , username " + storeRemeberMe.getUsername());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public HttpRemeberMeEntryPoint() {
|
||||
super();
|
||||
}
|
||||
|
||||
public HttpRemeberMeEntryPoint (boolean enable) {
|
||||
super();
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
public HttpRemeberMeEntryPoint(
|
||||
AbstractAuthenticationProvider authenticationProvider, AbstractRemeberMeService remeberMeService,
|
||||
ApplicationConfig applicationConfig,boolean enable) {
|
||||
super();
|
||||
this.enable = enable;
|
||||
this.applicationConfig = applicationConfig;
|
||||
this.authenticationProvider = authenticationProvider;
|
||||
this.remeberMeService = remeberMeService;
|
||||
}
|
||||
|
||||
public boolean isEnable() {
|
||||
return enable;
|
||||
}
|
||||
|
||||
public void setEnable(boolean enable) {
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
public void setApplicationConfig(ApplicationConfig applicationConfig) {
|
||||
this.applicationConfig = applicationConfig;
|
||||
}
|
||||
|
||||
public void setAuthenticationProvider(AbstractAuthenticationProvider authenticationProvider) {
|
||||
this.authenticationProvider = authenticationProvider;
|
||||
}
|
||||
|
||||
public void setRemeberMeService(AbstractRemeberMeService remeberMeService) {
|
||||
this.remeberMeService = remeberMeService;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.maxkey.authn.support.rememberme;
|
||||
|
||||
import org.maxkey.constants.ConstantsPersistence;
|
||||
import org.maxkey.persistence.redis.RedisConnectionFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
public class RemeberMeServiceFactory {
|
||||
private static final Logger _logger =
|
||||
LoggerFactory.getLogger(RemeberMeServiceFactory.class);
|
||||
|
||||
public AbstractRemeberMeService getService(
|
||||
int persistence,
|
||||
JdbcTemplate jdbcTemplate,
|
||||
RedisConnectionFactory redisConnFactory){
|
||||
|
||||
AbstractRemeberMeService remeberMeService = null;
|
||||
if (persistence == ConstantsPersistence.INMEMORY) {
|
||||
remeberMeService = new InMemoryRemeberMeService();
|
||||
_logger.debug("InMemoryRemeberMeService");
|
||||
} else if (persistence == ConstantsPersistence.JDBC) {
|
||||
//remeberMeService = new JdbcRemeberMeService(jdbcTemplate);
|
||||
_logger.debug("JdbcRemeberMeService not support ");
|
||||
} else if (persistence == ConstantsPersistence.REDIS) {
|
||||
remeberMeService = new RedisRemeberMeService(redisConnFactory);
|
||||
_logger.debug("RedisRemeberMeService");
|
||||
}
|
||||
return remeberMeService;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* 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.authn.support.wsfederation;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.maxkey.authn.AbstractAuthenticationProvider;
|
||||
import org.maxkey.configuration.ApplicationConfig;
|
||||
import org.maxkey.constants.ConstantsLoginType;
|
||||
import org.maxkey.util.StringUtils;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.opensaml.saml1.core.impl.AssertionImpl;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.servlet.AsyncHandlerInterceptor;
|
||||
|
||||
|
||||
public class HttpWsFederationEntryPoint implements AsyncHandlerInterceptor {
|
||||
private static final Logger _logger = LoggerFactory.getLogger(HttpWsFederationEntryPoint.class);
|
||||
|
||||
boolean enable;
|
||||
|
||||
ApplicationConfig applicationConfig;
|
||||
|
||||
AbstractAuthenticationProvider authenticationProvider ;
|
||||
|
||||
WsFederationService wsFederationService;
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
|
||||
boolean isAuthenticated= WebContext.isAuthenticated();
|
||||
String wsFederationWA = request.getParameter(WsFederationConstants.WA);
|
||||
String wsFederationWResult = request.getParameter(WsFederationConstants.WRESULT);
|
||||
|
||||
if(!enable
|
||||
|| isAuthenticated
|
||||
|| !applicationConfig.getLoginConfig().isWsFederation()
|
||||
|| wsFederationWA == null){
|
||||
return true;
|
||||
}
|
||||
|
||||
_logger.trace("WsFederation Login Start ...");
|
||||
_logger.trace("Request url : "+ request.getRequestURL());
|
||||
_logger.trace("Request URI : "+ request.getRequestURI());
|
||||
_logger.trace("Request ContextPath : "+ request.getContextPath());
|
||||
_logger.trace("Request ServletPath : "+ request.getServletPath());
|
||||
_logger.trace("RequestSessionId : "+ request.getRequestedSessionId());
|
||||
_logger.trace("isRequestedSessionIdValid : "+ request.isRequestedSessionIdValid());
|
||||
_logger.trace("getSession : "+ request.getSession(false));
|
||||
|
||||
// session not exists,session timeout,recreate new session
|
||||
if(request.getSession(false) == null) {
|
||||
_logger.trace("recreate new session .");
|
||||
request.getSession(true);
|
||||
}
|
||||
|
||||
_logger.trace("getSession.getId : "+ request.getSession().getId());
|
||||
|
||||
//for WsFederation Login
|
||||
_logger.debug("WsFederation : " + wsFederationWA +" , wsFederationWResult : " + wsFederationWResult);
|
||||
if(applicationConfig.getLoginConfig().isWsFederation()
|
||||
&& StringUtils.isNotEmpty(wsFederationWA)
|
||||
&& wsFederationWA.equalsIgnoreCase(WsFederationConstants.WSIGNIN)){
|
||||
_logger.debug("wresult : {}"+wsFederationWResult);
|
||||
|
||||
final String wctx = request.getParameter(WsFederationConstants.WCTX);
|
||||
_logger.debug("wctx : {}"+ wctx);
|
||||
|
||||
// create credentials
|
||||
final AssertionImpl assertion = WsFederationUtils.parseTokenFromString(wsFederationWResult);
|
||||
//Validate the signature
|
||||
if (assertion != null && WsFederationUtils.validateSignature(assertion, wsFederationService.getWsFederationConfiguration().getSigningCertificates())) {
|
||||
final WsFederationCredential wsFederationCredential = WsFederationUtils.createCredentialFromToken(assertion);
|
||||
|
||||
if (wsFederationCredential != null && wsFederationCredential.isValid(wsFederationService.getWsFederationConfiguration().getRelyingParty(),
|
||||
wsFederationService.getWsFederationConfiguration().getIdentifier(),
|
||||
wsFederationService.getWsFederationConfiguration().getTolerance())) {
|
||||
|
||||
//Give the library user a chance to change the attributes as necessary
|
||||
if (wsFederationService.getWsFederationConfiguration().getAttributeMutator() != null) {
|
||||
wsFederationService.getWsFederationConfiguration().getAttributeMutator().modifyAttributes(
|
||||
wsFederationCredential.getAttributes(),
|
||||
wsFederationService.getWsFederationConfiguration().getUpnSuffix());
|
||||
}
|
||||
|
||||
authenticationProvider.trustAuthentication(
|
||||
wsFederationCredential.getAttributes().get("").toString(),
|
||||
ConstantsLoginType.WSFEDERATION,
|
||||
"","","success");
|
||||
return true;
|
||||
} else {
|
||||
_logger.warn("SAML assertions are blank or no longer valid.");
|
||||
}
|
||||
} else {
|
||||
_logger.error("WS Requested Security Token is blank or the signature is not valid.");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public HttpWsFederationEntryPoint() {
|
||||
super();
|
||||
}
|
||||
|
||||
public HttpWsFederationEntryPoint (boolean enable) {
|
||||
super();
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
public HttpWsFederationEntryPoint(AbstractAuthenticationProvider authenticationProvider, WsFederationService wsFederationService,
|
||||
ApplicationConfig applicationConfig, boolean enable) {
|
||||
super();
|
||||
this.authenticationProvider = authenticationProvider;
|
||||
this.wsFederationService = wsFederationService;
|
||||
this.applicationConfig = applicationConfig;
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
public boolean isEnable() {
|
||||
return enable;
|
||||
}
|
||||
|
||||
public void setEnable(boolean enable) {
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
public void setApplicationConfig(ApplicationConfig applicationConfig) {
|
||||
this.applicationConfig = applicationConfig;
|
||||
}
|
||||
|
||||
public void setAuthenticationProvider(AbstractAuthenticationProvider authenticationProvider) {
|
||||
this.authenticationProvider = authenticationProvider;
|
||||
}
|
||||
|
||||
public void setWsFederationService(WsFederationService wsFederationService) {
|
||||
this.wsFederationService = wsFederationService;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -17,9 +17,7 @@
|
||||
|
||||
package org.maxkey.authn.support.wsfederation;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
public interface WsFederationService {
|
||||
public boolean login(String wsFederationWA,String wsFederationWResult,HttpServletRequest request);
|
||||
public WsFederationConfiguration getWsFederationConfiguration();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.authn.support.wsfederation;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
public class WsFederationServiceImpl implements WsFederationService{
|
||||
final static Logger _logger = LoggerFactory.getLogger(WsFederationServiceImpl.class);
|
||||
|
||||
private WsFederationConfiguration wsFederationConfiguration;
|
||||
|
||||
public void setWsFederationConfiguration(
|
||||
WsFederationConfiguration wsFederationConfiguration) {
|
||||
this.wsFederationConfiguration = wsFederationConfiguration;
|
||||
}
|
||||
|
||||
public WsFederationConfiguration getWsFederationConfiguration() {
|
||||
return wsFederationConfiguration;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* 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.autoconfigure;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.sql.DataSource;
|
||||
import org.maxkey.authn.AbstractAuthenticationProvider;
|
||||
import org.maxkey.authn.RealmAuthenticationProvider;
|
||||
import org.maxkey.authn.SavedRequestAwareAuthenticationSuccessHandler;
|
||||
import org.maxkey.authn.online.OnlineTicketServices;
|
||||
import org.maxkey.authn.online.OnlineTicketServicesFactory;
|
||||
import org.maxkey.authn.realm.AbstractAuthenticationRealm;
|
||||
import org.maxkey.authn.support.rememberme.AbstractRemeberMeService;
|
||||
import org.maxkey.authn.support.rememberme.RemeberMeServiceFactory;
|
||||
import org.maxkey.configuration.ApplicationConfig;
|
||||
import org.maxkey.constants.ConstantsProperties;
|
||||
import org.maxkey.crypto.password.LdapShaPasswordEncoder;
|
||||
import org.maxkey.crypto.password.Md4PasswordEncoder;
|
||||
import org.maxkey.crypto.password.NoOpPasswordEncoder;
|
||||
import org.maxkey.crypto.password.MessageDigestPasswordEncoder;
|
||||
import org.maxkey.crypto.password.SM3PasswordEncoder;
|
||||
import org.maxkey.crypto.password.StandardPasswordEncoder;
|
||||
import org.maxkey.password.onetimepwd.AbstractOtpAuthn;
|
||||
import org.maxkey.persistence.db.PasswordPolicyValidator;
|
||||
import org.maxkey.persistence.redis.RedisConnectionFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
|
||||
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
|
||||
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
|
||||
import org.maxkey.persistence.db.LoginService;
|
||||
import org.maxkey.persistence.db.LoginHistoryService;
|
||||
|
||||
|
||||
@Configuration
|
||||
@PropertySource(ConstantsProperties.applicationPropertySource)
|
||||
@PropertySource(ConstantsProperties.maxKeyPropertySource)
|
||||
public class AuthenticationAutoConfiguration implements InitializingBean {
|
||||
private static final Logger _logger =
|
||||
LoggerFactory.getLogger(AuthenticationAutoConfiguration.class);
|
||||
|
||||
|
||||
@Bean(name = "savedRequestSuccessHandler")
|
||||
public SavedRequestAwareAuthenticationSuccessHandler
|
||||
savedRequestAwareAuthenticationSuccessHandler() {
|
||||
return new SavedRequestAwareAuthenticationSuccessHandler();
|
||||
}
|
||||
|
||||
@Bean(name = "authenticationProvider")
|
||||
public AbstractAuthenticationProvider authenticationProvider(
|
||||
AbstractAuthenticationRealm authenticationRealm,
|
||||
ApplicationConfig applicationConfig,
|
||||
AbstractOtpAuthn tfaOtpAuthn,
|
||||
AbstractRemeberMeService remeberMeService,
|
||||
OnlineTicketServices onlineTicketServices
|
||||
) {
|
||||
_logger.debug("init authenticationProvider .");
|
||||
return new RealmAuthenticationProvider(
|
||||
authenticationRealm,
|
||||
applicationConfig,
|
||||
tfaOtpAuthn,
|
||||
remeberMeService,
|
||||
onlineTicketServices
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Bean(name = "transactionManager")
|
||||
public DataSourceTransactionManager transactionManager(DataSource dataSource) {
|
||||
return new DataSourceTransactionManager(dataSource);
|
||||
}
|
||||
|
||||
@Bean(name = "passwordPolicyValidator")
|
||||
public PasswordPolicyValidator passwordPolicyValidator(JdbcTemplate jdbcTemplate,MessageSource messageSource) {
|
||||
return new PasswordPolicyValidator(jdbcTemplate,messageSource);
|
||||
}
|
||||
|
||||
@Bean(name = "loginService")
|
||||
public LoginService LoginService(JdbcTemplate jdbcTemplate) {
|
||||
return new LoginService(jdbcTemplate);
|
||||
}
|
||||
@Bean(name = "loginHistoryService")
|
||||
public LoginHistoryService loginHistoryService(JdbcTemplate jdbcTemplate) {
|
||||
return new LoginHistoryService(jdbcTemplate);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Authentication Password Encoder .
|
||||
* @return
|
||||
*/
|
||||
@Bean(name = "passwordEncoder")
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
_logger.debug("init passwordEncoder .");
|
||||
String idForEncode = "bcrypt";
|
||||
Map<String ,PasswordEncoder > encoders = new HashMap<String ,PasswordEncoder>();
|
||||
encoders.put(idForEncode, new BCryptPasswordEncoder());
|
||||
encoders.put("plain", NoOpPasswordEncoder.getInstance());
|
||||
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
|
||||
encoders.put("scrypt", new SCryptPasswordEncoder());
|
||||
//md
|
||||
encoders.put("md4", new Md4PasswordEncoder());
|
||||
encoders.put("md5", new MessageDigestPasswordEncoder("MD5"));
|
||||
//sha
|
||||
encoders.put("sha1", new StandardPasswordEncoder("SHA-1",""));
|
||||
encoders.put("sha256", new StandardPasswordEncoder());
|
||||
encoders.put("sha384", new StandardPasswordEncoder("SHA-384",""));
|
||||
encoders.put("sha512", new StandardPasswordEncoder("SHA-512",""));
|
||||
|
||||
encoders.put("sm3", new SM3PasswordEncoder());
|
||||
|
||||
encoders.put("ldap", new LdapShaPasswordEncoder());
|
||||
|
||||
//idForEncode is default for encoder
|
||||
PasswordEncoder passwordEncoder =
|
||||
new DelegatingPasswordEncoder(idForEncode, encoders);
|
||||
|
||||
return passwordEncoder;
|
||||
}
|
||||
|
||||
/**
|
||||
* remeberMeService .
|
||||
* @return
|
||||
*/
|
||||
@Bean(name = "remeberMeService")
|
||||
public AbstractRemeberMeService remeberMeService(
|
||||
@Value("${config.server.persistence}") int persistence,
|
||||
@Value("${config.login.remeberme.validity}") int validity,
|
||||
JdbcTemplate jdbcTemplate,
|
||||
RedisConnectionFactory redisConnFactory) {
|
||||
return new RemeberMeServiceFactory().getService(persistence, jdbcTemplate, redisConnFactory);
|
||||
}
|
||||
|
||||
@Bean(name = "onlineTicketServices")
|
||||
public OnlineTicketServices onlineTicketServices(
|
||||
@Value("${config.server.persistence}") int persistence,
|
||||
JdbcTemplate jdbcTemplate,
|
||||
RedisConnectionFactory redisConnFactory) {
|
||||
return new OnlineTicketServicesFactory().getService(persistence, jdbcTemplate, redisConnFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,6 @@ import java.net.URI;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
|
||||
import org.maxkey.authn.AbstractAuthenticationProvider;
|
||||
import org.maxkey.authn.support.jwt.JwtLoginService;
|
||||
import org.maxkey.configuration.oidc.OIDCProviderMetadataDetails;
|
||||
import org.maxkey.constants.ConstantsProperties;
|
||||
@@ -126,11 +125,9 @@ public class JwtAuthnAutoConfiguration implements InitializingBean {
|
||||
@Bean(name = "jwtLoginService")
|
||||
public JwtLoginService jwtLoginService(
|
||||
DefaultJwtSigningAndValidationService jwtSignerValidationService,
|
||||
OIDCProviderMetadataDetails oidcProviderMetadata,
|
||||
AbstractAuthenticationProvider authenticationProvider) {
|
||||
OIDCProviderMetadataDetails oidcProviderMetadata) {
|
||||
|
||||
JwtLoginService jwtLoginService = new JwtLoginService(
|
||||
authenticationProvider,
|
||||
oidcProviderMetadata,
|
||||
jwtSignerValidationService
|
||||
);
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
description = "maxkey-authentication-otp"
|
||||
|
||||
|
||||
dependencies {
|
||||
//local jars
|
||||
compile fileTree(dir: '../maxkey-lib/', include: '*/*.jar')
|
||||
|
||||
compile project(":maxkey-common")
|
||||
compile project(":maxkey-core")
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
Manifest-Version: 1.0
|
||||
Class-Path:
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt;
|
||||
package org.maxkey.password.onetimepwd;
|
||||
|
||||
import org.maxkey.crypto.password.opt.token.AbstractOptTokenStore;
|
||||
import org.maxkey.crypto.password.opt.token.InMemoryOptTokenStore;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.password.onetimepwd.token.AbstractOtpTokenStore;
|
||||
import org.maxkey.password.onetimepwd.token.InMemoryOtpTokenStore;
|
||||
import org.maxkey.util.StringGenerator;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -29,10 +29,10 @@ import org.slf4j.LoggerFactory;
|
||||
* @author Administrator
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractOptAuthn {
|
||||
private static final Logger logger = LoggerFactory.getLogger(AbstractOptAuthn.class);
|
||||
public abstract class AbstractOtpAuthn {
|
||||
private static final Logger logger = LoggerFactory.getLogger(AbstractOtpAuthn.class);
|
||||
|
||||
protected AbstractOptTokenStore optTokenStore = new InMemoryOptTokenStore();
|
||||
protected AbstractOtpTokenStore optTokenStore = new InMemoryOtpTokenStore();
|
||||
|
||||
//验证码有效間隔
|
||||
protected int interval = 30;
|
||||
@@ -44,9 +44,9 @@ public abstract class AbstractOptAuthn {
|
||||
|
||||
StringGenerator stringGenerator;
|
||||
|
||||
protected String optType = OptTypes.TIMEBASED_OPT;
|
||||
protected String otpType = OtpTypes.TIMEBASED_OTP;
|
||||
|
||||
public static final class OptTypes {
|
||||
public static final class OtpTypes {
|
||||
// 手机
|
||||
public static String MOBILE = "MOBILE";
|
||||
// 短信
|
||||
@@ -54,13 +54,13 @@ public abstract class AbstractOptAuthn {
|
||||
// 邮箱
|
||||
public static String EMAIL = "EMAIL";
|
||||
//TIMEBASED_OPT
|
||||
public static String TIMEBASED_OPT = "TOPT";
|
||||
public static String TIMEBASED_OTP = "TOPT";
|
||||
// HmacOTP
|
||||
public static String HOTP_OPT = "HOTP";
|
||||
public static String HOTP_OTP = "HOTP";
|
||||
|
||||
public static String RSA_OPT = "RSA";
|
||||
public static String RSA_OTP = "RSA";
|
||||
|
||||
public static String CAP_OPT = "CAP";
|
||||
public static String CAP_OTP = "CAP";
|
||||
|
||||
}
|
||||
|
||||
@@ -134,13 +134,20 @@ public abstract class AbstractOptAuthn {
|
||||
this.crypto = crypto;
|
||||
}
|
||||
|
||||
public String getOptType() {
|
||||
return optType;
|
||||
public String getOtpType() {
|
||||
return otpType;
|
||||
}
|
||||
|
||||
public void setOptType(String optType) {
|
||||
this.optType = optType;
|
||||
public void setOtpType(String optType) {
|
||||
this.otpType = optType;
|
||||
}
|
||||
|
||||
public void setOptTokenStore(AbstractOtpTokenStore optTokenStore) {
|
||||
this.optTokenStore = optTokenStore;
|
||||
}
|
||||
|
||||
public void initPropertys() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt;
|
||||
package org.maxkey.password.onetimepwd;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt.algorithm;
|
||||
package org.maxkey.password.onetimepwd.algorithm;
|
||||
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt.algorithm;
|
||||
package org.maxkey.password.onetimepwd.algorithm;
|
||||
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt.algorithm;
|
||||
package org.maxkey.password.onetimepwd.algorithm;
|
||||
|
||||
public class KeyUriFormat {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt.algorithm;
|
||||
package org.maxkey.password.onetimepwd.algorithm;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt.algorithm;
|
||||
package org.maxkey.password.onetimepwd.algorithm;
|
||||
|
||||
import java.lang.reflect.UndeclaredThrowableException;
|
||||
import java.math.BigInteger;
|
||||
@@ -15,10 +15,10 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt.impl;
|
||||
package org.maxkey.password.onetimepwd.impl;
|
||||
|
||||
import org.maxkey.crypto.password.opt.AbstractOptAuthn;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.password.onetimepwd.AbstractOtpAuthn;
|
||||
|
||||
/**
|
||||
* Chip Authentication Program EMV stands for Europay, MasterCard and Visa, a
|
||||
@@ -30,12 +30,12 @@ import org.maxkey.domain.UserInfo;
|
||||
* @author Crystal.Sea
|
||||
*
|
||||
*/
|
||||
public class CapOtpAuthn extends AbstractOptAuthn {
|
||||
public class CapOtpAuthn extends AbstractOtpAuthn {
|
||||
|
||||
|
||||
|
||||
public CapOtpAuthn() {
|
||||
optType = OptTypes.CAP_OPT;
|
||||
otpType = OtpTypes.CAP_OTP;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -15,22 +15,22 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt.impl;
|
||||
package org.maxkey.password.onetimepwd.impl;
|
||||
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.maxkey.crypto.Base32Utils;
|
||||
import org.maxkey.crypto.password.opt.AbstractOptAuthn;
|
||||
import org.maxkey.crypto.password.opt.algorithm.TimeBasedOTP;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.password.onetimepwd.AbstractOtpAuthn;
|
||||
import org.maxkey.password.onetimepwd.algorithm.TimeBasedOTP;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class CounterBasedOtpAuthn extends AbstractOptAuthn {
|
||||
public class CounterBasedOtpAuthn extends AbstractOtpAuthn {
|
||||
private static final Logger _logger = LoggerFactory.getLogger(CounterBasedOtpAuthn.class);
|
||||
|
||||
|
||||
public CounterBasedOtpAuthn() {
|
||||
optType = OptTypes.HOTP_OPT;
|
||||
otpType = OtpTypes.HOTP_OTP;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -15,25 +15,26 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt.impl;
|
||||
package org.maxkey.password.onetimepwd.impl;
|
||||
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import org.maxkey.crypto.Base32Utils;
|
||||
import org.maxkey.crypto.password.opt.AbstractOptAuthn;
|
||||
import org.maxkey.crypto.password.opt.algorithm.HOTP;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.password.onetimepwd.AbstractOtpAuthn;
|
||||
import org.maxkey.password.onetimepwd.algorithm.HOTP;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class HotpOtpAuthn extends AbstractOptAuthn {
|
||||
public class HotpOtpAuthn extends AbstractOtpAuthn {
|
||||
private static final Logger _logger = LoggerFactory.getLogger(HotpOtpAuthn.class);
|
||||
|
||||
boolean addChecksum;
|
||||
int truncation = -1;
|
||||
|
||||
public HotpOtpAuthn() {
|
||||
optType = OptTypes.HOTP_OPT;
|
||||
otpType = OtpTypes.HOTP_OTP;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -15,20 +15,20 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt.impl;
|
||||
package org.maxkey.password.onetimepwd.impl;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import org.apache.commons.mail.DefaultAuthenticator;
|
||||
import org.apache.commons.mail.Email;
|
||||
import org.apache.commons.mail.SimpleEmail;
|
||||
import org.maxkey.configuration.EmailConfig;
|
||||
import org.maxkey.crypto.password.opt.AbstractOptAuthn;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.password.onetimepwd.AbstractOtpAuthn;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
public class MailOtpAuthn extends AbstractOptAuthn {
|
||||
public class MailOtpAuthn extends AbstractOtpAuthn {
|
||||
private static final Logger _logger = LoggerFactory.getLogger(MailOtpAuthn.class);
|
||||
|
||||
@Autowired
|
||||
@@ -38,7 +38,7 @@ public class MailOtpAuthn extends AbstractOptAuthn {
|
||||
String messageTemplate = "{0} You Token is {1} , it validity in {2} minutes.";
|
||||
|
||||
public MailOtpAuthn() {
|
||||
optType = OptTypes.EMAIL;
|
||||
otpType = OtpTypes.EMAIL;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -68,7 +68,7 @@ public class MailOtpAuthn extends AbstractOptAuthn {
|
||||
userInfo,
|
||||
token,
|
||||
userInfo.getMobile(),
|
||||
OptTypes.EMAIL);
|
||||
OtpTypes.EMAIL);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -78,7 +78,7 @@ public class MailOtpAuthn extends AbstractOptAuthn {
|
||||
|
||||
@Override
|
||||
public boolean validate(UserInfo userInfo, String token) {
|
||||
return this.optTokenStore.validate(userInfo, token, OptTypes.EMAIL, interval);
|
||||
return this.optTokenStore.validate(userInfo, token, OtpTypes.EMAIL, interval);
|
||||
}
|
||||
|
||||
public void setEmailConfig(EmailConfig emailConfig) {
|
||||
@@ -15,17 +15,17 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt.impl;
|
||||
package org.maxkey.password.onetimepwd.impl;
|
||||
|
||||
import org.maxkey.crypto.password.opt.AbstractOptAuthn;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.password.onetimepwd.AbstractOtpAuthn;
|
||||
|
||||
public class MobileOtpAuthn extends AbstractOptAuthn {
|
||||
public class MobileOtpAuthn extends AbstractOtpAuthn {
|
||||
|
||||
|
||||
|
||||
public MobileOtpAuthn() {
|
||||
optType = OptTypes.SMS;
|
||||
otpType = OtpTypes.SMS;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -15,10 +15,10 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt.impl;
|
||||
package org.maxkey.password.onetimepwd.impl;
|
||||
|
||||
import org.maxkey.crypto.password.opt.AbstractOptAuthn;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.password.onetimepwd.AbstractOtpAuthn;
|
||||
|
||||
/**
|
||||
* Chip Authentication Program EMV stands for Europay, MasterCard and Visa, a
|
||||
@@ -30,12 +30,12 @@ import org.maxkey.domain.UserInfo;
|
||||
* @author Crystal.Sea
|
||||
*
|
||||
*/
|
||||
public class RsaOtpAuthn extends AbstractOptAuthn {
|
||||
public class RsaOtpAuthn extends AbstractOtpAuthn {
|
||||
|
||||
|
||||
|
||||
public RsaOtpAuthn() {
|
||||
optType = OptTypes.RSA_OPT;
|
||||
otpType = OtpTypes.RSA_OTP;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -15,19 +15,20 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt.impl;
|
||||
package org.maxkey.password.onetimepwd.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.maxkey.constants.ConstantsProperties;
|
||||
import org.maxkey.crypto.password.opt.AbstractOptAuthn;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.password.onetimepwd.AbstractOtpAuthn;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
public class SmsOtpAuthn extends AbstractOptAuthn {
|
||||
public class SmsOtpAuthn extends AbstractOtpAuthn {
|
||||
private static final Logger logger = LoggerFactory.getLogger(SmsOtpAuthn.class);
|
||||
|
||||
protected Properties properties;
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt.impl;
|
||||
package org.maxkey.password.onetimepwd.impl;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
@@ -23,13 +23,13 @@ import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.maxkey.crypto.Base32Utils;
|
||||
import org.maxkey.crypto.password.opt.AbstractOptAuthn;
|
||||
import org.maxkey.crypto.password.opt.algorithm.TimeBasedOTP;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.password.onetimepwd.AbstractOtpAuthn;
|
||||
import org.maxkey.password.onetimepwd.algorithm.TimeBasedOTP;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class TimeBasedOtpAuthn extends AbstractOptAuthn {
|
||||
public class TimeBasedOtpAuthn extends AbstractOtpAuthn {
|
||||
private static final Logger _logger = LoggerFactory.getLogger(TimeBasedOtpAuthn.class);
|
||||
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt.impl.sms;
|
||||
package org.maxkey.password.onetimepwd.impl.sms;
|
||||
|
||||
import com.aliyuncs.CommonRequest;
|
||||
import com.aliyuncs.CommonResponse;
|
||||
@@ -26,8 +26,8 @@ import com.aliyuncs.profile.DefaultProfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.maxkey.crypto.password.opt.impl.SmsOtpAuthn;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.password.onetimepwd.impl.SmsOtpAuthn;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -42,7 +42,7 @@ public class SmsOtpAuthnAliyun extends SmsOtpAuthn {
|
||||
private static final Logger logger = LoggerFactory.getLogger(SmsOtpAuthnAliyun.class);
|
||||
|
||||
public SmsOtpAuthnAliyun() {
|
||||
optType = OptTypes.SMS;
|
||||
otpType = OtpTypes.SMS;
|
||||
}
|
||||
|
||||
//请替换你在管理后台应用下申请的accessKeyId
|
||||
@@ -83,7 +83,7 @@ public class SmsOtpAuthnAliyun extends SmsOtpAuthn {
|
||||
userInfo,
|
||||
token,
|
||||
userInfo.getMobile(),
|
||||
OptTypes.SMS);
|
||||
OtpTypes.SMS);
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@@ -95,7 +95,7 @@ public class SmsOtpAuthnAliyun extends SmsOtpAuthn {
|
||||
|
||||
@Override
|
||||
public boolean validate(UserInfo userInfo, String token) {
|
||||
return this.optTokenStore.validate(userInfo, token, OptTypes.SMS, interval);
|
||||
return this.optTokenStore.validate(userInfo, token, OtpTypes.SMS, interval);
|
||||
}
|
||||
|
||||
public String getAccessKeyId() {
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt.impl.sms;
|
||||
package org.maxkey.password.onetimepwd.impl.sms;
|
||||
|
||||
import com.tencentcloudapi.common.Credential;
|
||||
import com.tencentcloudapi.common.profile.ClientProfile;
|
||||
@@ -26,8 +26,8 @@ import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.maxkey.crypto.password.opt.impl.SmsOtpAuthn;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.password.onetimepwd.impl.SmsOtpAuthn;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -52,7 +52,7 @@ public class SmsOtpAuthnTencentCloud extends SmsOtpAuthn {
|
||||
String sign;
|
||||
|
||||
public SmsOtpAuthnTencentCloud() {
|
||||
optType = OptTypes.SMS;
|
||||
otpType = OtpTypes.SMS;
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ public class SmsOtpAuthnTencentCloud extends SmsOtpAuthn {
|
||||
userInfo,
|
||||
token,
|
||||
userInfo.getMobile(),
|
||||
OptTypes.SMS);
|
||||
OtpTypes.SMS);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ public class SmsOtpAuthnTencentCloud extends SmsOtpAuthn {
|
||||
|
||||
@Override
|
||||
public boolean validate(UserInfo userInfo, String token) {
|
||||
return this.optTokenStore.validate(userInfo, token, OptTypes.SMS, interval);
|
||||
return this.optTokenStore.validate(userInfo, token, OtpTypes.SMS, interval);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt.impl.sms;
|
||||
package org.maxkey.password.onetimepwd.impl.sms;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -29,8 +29,8 @@ import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.maxkey.crypto.password.opt.impl.SmsOtpAuthn;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.password.onetimepwd.impl.SmsOtpAuthn;
|
||||
import org.maxkey.util.JsonUtils;
|
||||
import org.maxkey.util.StringGenerator;
|
||||
import org.slf4j.Logger;
|
||||
@@ -45,7 +45,7 @@ public class SmsOtpAuthnYunxin extends SmsOtpAuthn {
|
||||
private static final Logger logger = LoggerFactory.getLogger(SmsOtpAuthnYunxin.class);
|
||||
|
||||
public SmsOtpAuthnYunxin() {
|
||||
optType = OptTypes.SMS;
|
||||
otpType = OtpTypes.SMS;
|
||||
}
|
||||
|
||||
//发送验证码的请求路径URL
|
||||
@@ -122,7 +122,7 @@ public class SmsOtpAuthnYunxin extends SmsOtpAuthn {
|
||||
userInfo,
|
||||
yunxinSms.getObj(),
|
||||
userInfo.getMobile(),
|
||||
OptTypes.SMS);
|
||||
OtpTypes.SMS);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
logger.error(" produce code error ", e);
|
||||
@@ -137,7 +137,7 @@ public class SmsOtpAuthnYunxin extends SmsOtpAuthn {
|
||||
|
||||
@Override
|
||||
public boolean validate(UserInfo userInfo, String token) {
|
||||
return this.optTokenStore.validate(userInfo, token, OptTypes.SMS, interval);
|
||||
return this.optTokenStore.validate(userInfo, token, OtpTypes.SMS, interval);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt.impl.sms;
|
||||
package org.maxkey.password.onetimepwd.impl.sms;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt.token;
|
||||
package org.maxkey.password.onetimepwd.token;
|
||||
|
||||
import org.maxkey.domain.UserInfo;
|
||||
|
||||
public abstract class AbstractOptTokenStore {
|
||||
public abstract class AbstractOtpTokenStore {
|
||||
|
||||
public abstract void store(UserInfo userInfo, String token, String receiver, String type);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt.token;
|
||||
package org.maxkey.password.onetimepwd.token;
|
||||
|
||||
import org.ehcache.UserManagedCache;
|
||||
import org.ehcache.config.builders.ExpiryPolicyBuilder;
|
||||
@@ -24,13 +24,13 @@ import org.joda.time.DateTime;
|
||||
import org.joda.time.Duration;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.maxkey.constants.ConstantsTimeInterval;
|
||||
import org.maxkey.crypto.password.opt.OneTimePassword;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.password.onetimepwd.OneTimePassword;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class InMemoryOptTokenStore extends AbstractOptTokenStore {
|
||||
private static final Logger logger = LoggerFactory.getLogger(InMemoryOptTokenStore.class);
|
||||
public class InMemoryOtpTokenStore extends AbstractOtpTokenStore {
|
||||
private static final Logger logger = LoggerFactory.getLogger(InMemoryOtpTokenStore.class);
|
||||
|
||||
protected static final UserManagedCache<String, OneTimePassword> optTokenStore =
|
||||
UserManagedCacheBuilder.newUserManagedCacheBuilder(String.class, OneTimePassword.class)
|
||||
@@ -73,7 +73,7 @@ public class InMemoryOptTokenStore extends AbstractOptTokenStore {
|
||||
return false;
|
||||
}
|
||||
|
||||
public InMemoryOptTokenStore() {
|
||||
public InMemoryOtpTokenStore() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -15,21 +15,26 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.crypto.password.opt.token;
|
||||
package org.maxkey.password.onetimepwd.token;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.maxkey.constants.ConstantsTimeInterval;
|
||||
import org.maxkey.crypto.password.opt.OneTimePassword;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.password.onetimepwd.OneTimePassword;
|
||||
import org.maxkey.persistence.redis.RedisConnection;
|
||||
import org.maxkey.persistence.redis.RedisConnectionFactory;
|
||||
|
||||
public class RedisOptTokenStore extends AbstractOptTokenStore {
|
||||
public class RedisOtpTokenStore extends AbstractOtpTokenStore {
|
||||
|
||||
protected int validitySeconds = ConstantsTimeInterval.ONE_MINUTE * 5;
|
||||
|
||||
RedisConnectionFactory connectionFactory;
|
||||
|
||||
public RedisOtpTokenStore(RedisConnectionFactory connectionFactory) {
|
||||
super();
|
||||
this.connectionFactory = connectionFactory;
|
||||
}
|
||||
|
||||
public static String PREFIX = "REDIS_OTP_SERVICE_";
|
||||
|
||||
@Override
|
||||
@@ -22,8 +22,8 @@ import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import org.maxkey.crypto.Base32Utils;
|
||||
import org.maxkey.crypto.password.opt.algorithm.HOTP;
|
||||
import org.maxkey.crypto.password.opt.algorithm.HmacOTP;
|
||||
import org.maxkey.password.onetimepwd.algorithm.HOTP;
|
||||
import org.maxkey.password.onetimepwd.algorithm.HmacOTP;
|
||||
|
||||
|
||||
public class HmacOTPTest {
|
||||
@@ -19,7 +19,7 @@ package org.maxkey.otp.algorithm;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.maxkey.crypto.password.opt.algorithm.KeyUriFormat;
|
||||
import org.maxkey.password.onetimepwd.algorithm.KeyUriFormat;
|
||||
import org.maxkey.util.QRCode;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
@@ -26,7 +26,7 @@ import java.util.TimeZone;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.maxkey.crypto.Base32Utils;
|
||||
import org.maxkey.crypto.HexUtils;
|
||||
import org.maxkey.crypto.password.opt.algorithm.TimeBasedOTP;
|
||||
import org.maxkey.password.onetimepwd.algorithm.TimeBasedOTP;
|
||||
/**
|
||||
* goole
|
||||
* @author Crystal.Sea
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
description = "maxkey-authentication-social"
|
||||
|
||||
|
||||
dependencies {
|
||||
//local jars
|
||||
compile fileTree(dir: '../maxkey-lib/', include: '*/*.jar')
|
||||
|
||||
compile project(":maxkey-common")
|
||||
compile project(":maxkey-core")
|
||||
compile project(":maxkey-persistence")
|
||||
compile project(":maxkey-authentications:maxkey-authentication-core")
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
Manifest-Version: 1.0
|
||||
Class-Path:
|
||||
|
||||
@@ -33,9 +33,9 @@ public class JdbcSocialsAssociateService implements SocialsAssociateService{
|
||||
|
||||
private static final String DEFAULT_DEFAULT_INSERT_STATEMENT = "INSERT INTO MXK_SOCIALS_ASSOCIATE(ID, UID , USERNAME , PROVIDER , SOCIALUID , ACCESSTOKEN , SOCIALUSERINFO , EXATTRIBUTE )VALUES( ? , ? , ? , ? , ?, ? , ? , ?)";
|
||||
|
||||
private static final String DEFAULT_DEFAULT_SIGNON_SELECT_STATEMENT = "SELECT ID, UID , USERNAME , PROVIDER , SOCIALUID , ACCESSTOKEN , SOCIALUSERINFO , EXATTRIBUTE FROM MXK_SOCIALS_ASSOCIATE WHERE PROVIDER = ? AND SOCIALUID = ?";
|
||||
private static final String DEFAULT_DEFAULT_SIGNON_SELECT_STATEMENT = "SELECT ID, UID , USERNAME , PROVIDER , SOCIALUID , ACCESSTOKEN , SOCIALUSERINFO , EXATTRIBUTE , CREATEDDATE , UPDATEDDATE FROM MXK_SOCIALS_ASSOCIATE WHERE PROVIDER = ? AND SOCIALUID = ?";
|
||||
|
||||
private static final String DEFAULT_DEFAULT_BIND_SELECT_STATEMENT = "SELECT ID, UID , USERNAME , PROVIDER , SOCIALUID , ACCESSTOKEN , SOCIALUSERINFO , EXATTRIBUTE FROM MXK_SOCIALS_ASSOCIATE WHERE UID = ?" ;
|
||||
private static final String DEFAULT_DEFAULT_BIND_SELECT_STATEMENT = "SELECT ID, UID , USERNAME , PROVIDER , SOCIALUID , ACCESSTOKEN , SOCIALUSERINFO , EXATTRIBUTE , CREATEDDATE , UPDATEDDATE FROM MXK_SOCIALS_ASSOCIATE WHERE UID = ?" ;
|
||||
|
||||
private static final String DEFAULT_DEFAULT_DELETE_STATEMENT = "DELETE FROM MXK_SOCIALS_ASSOCIATE WHERE UID = ? AND PROVIDER = ?";
|
||||
|
||||
@@ -119,6 +119,8 @@ public class JdbcSocialsAssociateService implements SocialsAssociateService{
|
||||
socialsAssociate.setAccessToken(rs.getString(6));
|
||||
socialsAssociate.setSocialUserInfo(rs.getString(7));
|
||||
socialsAssociate.setExAttribute(rs.getString(8));
|
||||
socialsAssociate.setCreatedDate(rs.getString(9));
|
||||
socialsAssociate.setUpdatedDate(rs.getString(10));
|
||||
return socialsAssociate;
|
||||
}
|
||||
}
|
||||
@@ -29,9 +29,13 @@ public class SocialSignOnProvider {
|
||||
private String clientId;
|
||||
private String clientSecret;
|
||||
private String accountId;
|
||||
private String bindTime;
|
||||
private String unBindTime;
|
||||
private String lastLoginTime;
|
||||
private int sortOrder;
|
||||
|
||||
|
||||
|
||||
private boolean userBind;
|
||||
|
||||
/**
|
||||
@@ -105,11 +109,58 @@ public class SocialSignOnProvider {
|
||||
this.userBind = userBind;
|
||||
}
|
||||
|
||||
|
||||
public String getBindTime() {
|
||||
return bindTime;
|
||||
}
|
||||
|
||||
public void setBindTime(String bindTime) {
|
||||
this.bindTime = bindTime;
|
||||
}
|
||||
|
||||
public String getUnBindTime() {
|
||||
return unBindTime;
|
||||
}
|
||||
|
||||
public void setUnBindTime(String unBindTime) {
|
||||
this.unBindTime = unBindTime;
|
||||
}
|
||||
|
||||
public String getLastLoginTime() {
|
||||
return lastLoginTime;
|
||||
}
|
||||
|
||||
public void setLastLoginTime(String lastLoginTime) {
|
||||
this.lastLoginTime = lastLoginTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SocialSignOnProvider [provider=" + provider + ", providerName=" + providerName + ", icon=" + icon
|
||||
+ ", clientId=" + clientId + ", clientSecret=" + clientSecret + ", accountId=" + accountId
|
||||
+ ", sortOrder=" + sortOrder + ", userBind=" + userBind + "]";
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("SocialSignOnProvider [provider=");
|
||||
builder.append(provider);
|
||||
builder.append(", providerName=");
|
||||
builder.append(providerName);
|
||||
builder.append(", icon=");
|
||||
builder.append(icon);
|
||||
builder.append(", clientId=");
|
||||
builder.append(clientId);
|
||||
builder.append(", clientSecret=");
|
||||
builder.append(clientSecret);
|
||||
builder.append(", accountId=");
|
||||
builder.append(accountId);
|
||||
builder.append(", bindTime=");
|
||||
builder.append(bindTime);
|
||||
builder.append(", unBindTime=");
|
||||
builder.append(unBindTime);
|
||||
builder.append(", lastLoginTime=");
|
||||
builder.append(lastLoginTime);
|
||||
builder.append(", sortOrder=");
|
||||
builder.append(sortOrder);
|
||||
builder.append(", userBind=");
|
||||
builder.append(userBind);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -69,9 +69,39 @@ public class SocialSignOnProviderService{
|
||||
authRequest = new AuthLinkedinRequest(authConfig);
|
||||
}else if(provider.equalsIgnoreCase("DingTalk")) {
|
||||
authRequest = new AuthDingTalkRequest(authConfig);
|
||||
}
|
||||
|
||||
|
||||
}else if(provider.equalsIgnoreCase("gitee")) {
|
||||
authRequest = new AuthGiteeRequest(authConfig);
|
||||
}else if(provider.equalsIgnoreCase("Baidu")) {
|
||||
authRequest = new AuthBaiduRequest(authConfig);
|
||||
}else if(provider.equalsIgnoreCase("Douyin")) {
|
||||
authRequest = new AuthDouyinRequest(authConfig);
|
||||
}else if(provider.equalsIgnoreCase("Eleme")) {
|
||||
authRequest = new AuthElemeRequest(authConfig);
|
||||
}else if(provider.equalsIgnoreCase("Feishu")) {
|
||||
authRequest = new AuthFeishuRequest(authConfig);
|
||||
}else if(provider.equalsIgnoreCase("Github")) {
|
||||
authRequest = new AuthGithubRequest(authConfig);
|
||||
}else if(provider.equalsIgnoreCase("Gitlab")) {
|
||||
authRequest = new AuthGitlabRequest(authConfig);
|
||||
}else if(provider.equalsIgnoreCase("Huawei")) {
|
||||
authRequest = new AuthHuaweiRequest(authConfig);
|
||||
}else if(provider.equalsIgnoreCase("jd")) {
|
||||
authRequest = new AuthJdRequest(authConfig);
|
||||
}else if(provider.equalsIgnoreCase("Meituan")) {
|
||||
authRequest = new AuthMeituanRequest(authConfig);
|
||||
}else if(provider.equalsIgnoreCase("Mi")) {
|
||||
authRequest = new AuthMiRequest(authConfig);
|
||||
}else if(provider.equalsIgnoreCase("Oschina")) {
|
||||
authRequest = new AuthOschinaRequest(authConfig);
|
||||
}else if(provider.equalsIgnoreCase("Taobao")) {
|
||||
authRequest = new AuthTaobaoRequest(authConfig);
|
||||
}else if(provider.equalsIgnoreCase("Toutiao")) {
|
||||
authRequest = new AuthToutiaoRequest(authConfig);
|
||||
}else if(provider.equalsIgnoreCase("WeChatQyQrcode")) {
|
||||
authRequest = new AuthWeChatEnterpriseQrcodeRequest(authConfig);
|
||||
}else if(provider.equalsIgnoreCase("WeChatQyWeb")) {
|
||||
authRequest = new AuthWeChatEnterpriseWebRequest(authConfig);
|
||||
}
|
||||
|
||||
return authRequest;
|
||||
}
|
||||
@@ -37,6 +37,8 @@ public class SocialsAssociate extends JpaBaseDomain {
|
||||
private String socialUserInfo;
|
||||
private String accessToken;
|
||||
private String exAttribute;
|
||||
private String createdDate;
|
||||
private String updatedDate;
|
||||
|
||||
public SocialsAssociate() {}
|
||||
|
||||
@@ -110,11 +112,46 @@ public class SocialsAssociate extends JpaBaseDomain {
|
||||
this.exAttribute = exAttribute;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SocialSignOnUserToken [provider=" + provider + ", uid=" + uid
|
||||
+ ", socialuid=" + socialuid + ", socialUserInfo="
|
||||
+ socialUserInfo + ", accessToken=" + accessToken
|
||||
+ ", exAttribute=" + exAttribute + "]";
|
||||
}
|
||||
public String getCreatedDate() {
|
||||
return createdDate;
|
||||
}
|
||||
|
||||
public void setCreatedDate(String createdDate) {
|
||||
this.createdDate = createdDate;
|
||||
}
|
||||
|
||||
public String getUpdatedDate() {
|
||||
return updatedDate;
|
||||
}
|
||||
|
||||
public void setUpdatedDate(String updatedDate) {
|
||||
this.updatedDate = updatedDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("SocialsAssociate [id=");
|
||||
builder.append(id);
|
||||
builder.append(", provider=");
|
||||
builder.append(provider);
|
||||
builder.append(", uid=");
|
||||
builder.append(uid);
|
||||
builder.append(", username=");
|
||||
builder.append(username);
|
||||
builder.append(", socialuid=");
|
||||
builder.append(socialuid);
|
||||
builder.append(", socialUserInfo=");
|
||||
builder.append(socialUserInfo);
|
||||
builder.append(", accessToken=");
|
||||
builder.append(accessToken);
|
||||
builder.append(", exAttribute=");
|
||||
builder.append(exAttribute);
|
||||
builder.append(", createdDate=");
|
||||
builder.append(createdDate);
|
||||
builder.append(", updatedDate=");
|
||||
builder.append(updatedDate);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,9 @@ public class SocialSignOnAutoConfiguration implements InitializingBean {
|
||||
socialSignOnProvider.setClientId(clientId);
|
||||
socialSignOnProvider.setClientSecret(clientSecret);
|
||||
socialSignOnProvider.setSortOrder(Integer.valueOf(sortOrder));
|
||||
_logger.debug("socialSignOnProvider " + socialSignOnProvider);
|
||||
_logger.debug("socialSignOnProvider " + socialSignOnProvider.getProvider()
|
||||
+ "(" + socialSignOnProvider.getProviderName()+")");
|
||||
_logger.trace("socialSignOnProvider " + socialSignOnProvider);
|
||||
socialSignOnProviderList.add(socialSignOnProvider);
|
||||
}
|
||||
socialSignOnProviderService.setSocialSignOnProviders(socialSignOnProviderList);
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* 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.authn.support.wsfederation;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.maxkey.authn.AbstractAuthenticationProvider;
|
||||
import org.maxkey.constants.ConstantsLoginType;
|
||||
import org.maxkey.util.StringUtils;
|
||||
import org.opensaml.saml1.core.impl.AssertionImpl;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
|
||||
public class WsFederationServiceImpl implements WsFederationService{
|
||||
final static Logger _logger = LoggerFactory.getLogger(WsFederationServiceImpl.class);
|
||||
|
||||
private WsFederationConfiguration wsFederationConfiguration;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("authenticationProvider")
|
||||
AbstractAuthenticationProvider authenticationProvider ;
|
||||
|
||||
public boolean login(String wsFederationWA,String wsFederationWResult,HttpServletRequest request){
|
||||
// it's an authentication
|
||||
if (StringUtils.isNotEmpty(wsFederationWA) && wsFederationWA.equalsIgnoreCase(WsFederationConstants.WSIGNIN)) {
|
||||
_logger.debug("wresult : {}"+wsFederationWResult);
|
||||
|
||||
final String wctx = request.getParameter(WsFederationConstants.WCTX);
|
||||
_logger.debug("wctx : {}"+ wctx);
|
||||
|
||||
// create credentials
|
||||
final AssertionImpl assertion = WsFederationUtils.parseTokenFromString(wsFederationWResult);
|
||||
//Validate the signature
|
||||
if (assertion != null && WsFederationUtils.validateSignature(assertion, wsFederationConfiguration.getSigningCertificates())) {
|
||||
final WsFederationCredential wsFederationCredential = WsFederationUtils.createCredentialFromToken(assertion);
|
||||
|
||||
if (wsFederationCredential != null && wsFederationCredential.isValid(wsFederationConfiguration.getRelyingParty(),
|
||||
wsFederationConfiguration.getIdentifier(),
|
||||
wsFederationConfiguration.getTolerance())) {
|
||||
|
||||
//Give the library user a chance to change the attributes as necessary
|
||||
if (wsFederationConfiguration.getAttributeMutator() != null) {
|
||||
wsFederationConfiguration.getAttributeMutator().modifyAttributes(
|
||||
wsFederationCredential.getAttributes(),
|
||||
wsFederationConfiguration.getUpnSuffix());
|
||||
}
|
||||
|
||||
authenticationProvider.trustAuthentication(
|
||||
wsFederationCredential.getAttributes().get("").toString(),
|
||||
ConstantsLoginType.WSFEDERATION,
|
||||
"","","success");
|
||||
return true;
|
||||
} else {
|
||||
_logger.warn("SAML assertions are blank or no longer valid.");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
_logger.error("WS Requested Security Token is blank or the signature is not valid.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setWsFederationConfiguration(
|
||||
WsFederationConfiguration wsFederationConfiguration) {
|
||||
this.wsFederationConfiguration = wsFederationConfiguration;
|
||||
}
|
||||
|
||||
}
|
||||
7
maxkey-common/build.gradle
Normal file
7
maxkey-common/build.gradle
Normal file
@@ -0,0 +1,7 @@
|
||||
description = "maxkey-common"
|
||||
|
||||
dependencies {
|
||||
//local jars
|
||||
compile fileTree(dir: '../maxkey-lib/', include: '*/*.jar')
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user