v2.0.0GA
v2.0.0GA
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# <img src="http://www.maxkey.top/images/logo.jpg" width="45px">MaxKey
|
||||
|
||||
<b>MaxKey(马克思的钥匙)</b>用户单点登录认证系统(Sigle Sign On System),寓意是最大钥匙,是<b>业界领先的企业级IAM身份管理和身份认证产品</b>,支持OAuth 2.0/OpenID Connect、SAML 2.0、JWT、CAS等标准化的开放协议,提供<b>简单、标准、安全和开放</b>的用户身份管理(IDM)、身份认证(AM)、单点登录(SSO)、资源管理和权限管理等。
|
||||
<b>MaxKey(马克思的钥匙)</b>用户单点登录认证系统(Sigle Sign On System),寓意是最大钥匙,是<b>业界领先的企业级IAM身份管理和身份认证产品</b>,支持OAuth 2.0/OpenID Connect、SAML 2.0、JWT、CAS等标准化的开放协议,提供<b>简单、标准、安全和开放</b>的用户身份管理(IDM)、身份认证(AM)、单点登录(SSO)、RBAC权限管理和资源管理等。
|
||||
|
||||
MaxKey <a href="https://www.maxkey.top" target="_blank"><b>官方文档</b></a> | <a href="https://github.com/shimingxy/MaxKey" target="_blank"><b>GitHub</b></a> | <a href="https://gitee.com/shimingxy/MaxKey" target="_blank"><b>码云(Gitee)</b></a>
|
||||
|
||||
@@ -95,3 +95,9 @@ QQ交流群:<b>434469201</b> | 邮箱EMAIL: <b>shimingxy@163.com</b>
|
||||
SCIM 2 Support-System for Cross-domain Identity Management
|
||||
|
||||
Apache Kafka Support
|
||||
|
||||
企业微信支持
|
||||
|
||||
钉钉支持
|
||||
|
||||
动态用户组实现(基于用户属性或机构)
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
*(MAXKEY-200618) 修复更新应用时状态问题
|
||||
*(MAXKEY-200619) REST API 机构和用户接口实现
|
||||
*(MAXKEY-200620) 代码优化及命名调整
|
||||
*(MAXKEY-200621) 依赖jar升级,消除非必要依赖
|
||||
*(MAXKEY-200621) CAS协议增强
|
||||
*(MAXKEY-200622) 机构变更时JSON序列化错误修复
|
||||
*(MAXKEY-200623) 依赖jar升级,消除非必要依赖
|
||||
spring 5.2.7.RELEASE
|
||||
springBoot 2.3.1.RELEASE
|
||||
springSecurity 5.3.2.RELEASE
|
||||
@@ -29,6 +31,9 @@
|
||||
tomcat-embed 9.0.35
|
||||
mybatis 3.5.5
|
||||
mybatis-jpa-extra 2.1
|
||||
tomcat-embed 9.0.36
|
||||
simple-http 1.0.2
|
||||
JustAuth 1.15.6
|
||||
|
||||
MaxKey v 1.4.0 GA 2020/05/01
|
||||
*(MAXKEY-200501) 登录错误修复
|
||||
|
||||
@@ -188,6 +188,7 @@ subprojects {
|
||||
//compile group: 'org.springframework', name: 'spring-websocket', version: "${springVersion}"
|
||||
testCompile group: 'org.springframework', name: 'spring-test', version: "${springVersion}"
|
||||
|
||||
//kafka support
|
||||
// https://mvnrepository.com/artifact/org.apache.kafka/kafka-clients
|
||||
compile group: 'org.apache.kafka', name: 'kafka-clients', version: '2.5.0'
|
||||
// https://mvnrepository.com/artifact/org.springframework.kafka/spring-kafka
|
||||
@@ -195,7 +196,6 @@ subprojects {
|
||||
// https://mvnrepository.com/artifact/org.springframework.retry/spring-retry
|
||||
compile group: 'org.springframework.retry', name: 'spring-retry', version: '1.3.0'
|
||||
|
||||
|
||||
//spring-security
|
||||
compile group: 'org.springframework.security', name: 'spring-security-core', version: "${springSecurityVersion}"
|
||||
compile group: 'org.springframework.security', name: 'spring-security-web', version: "${springSecurityVersion}"
|
||||
@@ -220,8 +220,8 @@ subprojects {
|
||||
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'
|
||||
compile group: 'me.zhyd.oauth', name: 'JustAuth', version: '1.15.1'
|
||||
compile group: 'com.xkcoding.http', name: 'simple-http', version: '1.0.2'
|
||||
compile group: 'me.zhyd.oauth', name: 'JustAuth', version: '1.15.6'
|
||||
//common
|
||||
compile group: 'org.javassist', name: 'javassist', version: '3.23.0-GA'
|
||||
compile group: 'org.owasp.esapi', name: 'esapi', version: '2.2.0.0'
|
||||
@@ -300,7 +300,7 @@ subprojects {
|
||||
compile group: 'com.tencentcloudapi', name: 'tencentcloud-sdk-java', version: '3.1.33'
|
||||
|
||||
//tomcat embed
|
||||
compile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '9.0.35'
|
||||
compile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '9.0.36'
|
||||
compile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-logging-juli', version: '8.5.2'
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ public class Organization2Activedirectory extends OrganizationConnector{
|
||||
SearchControls constraints = new SearchControls();
|
||||
constraints.setSearchScope(ldapUtils.getSearchScope());
|
||||
NamingEnumeration<SearchResult> results = ldapUtils.getConnection()
|
||||
.search(ldapUtils.getBaseDN(), "(&(objectClass=organizationalUnit)(description="+organization.getpId()+"))", constraints);
|
||||
.search(ldapUtils.getBaseDN(), "(&(objectClass=organizationalUnit)(description="+organization.getParentId()+"))", constraints);
|
||||
String rdn="";
|
||||
if (results == null || !results.hasMore()) {
|
||||
rdn=ldapUtils.getBaseDN();
|
||||
|
||||
@@ -31,7 +31,7 @@ public class Organization2Ldap extends OrganizationConnector{
|
||||
SearchControls constraints = new SearchControls();
|
||||
constraints.setSearchScope(ldapUtils.getSearchScope());
|
||||
NamingEnumeration<SearchResult> results = ldapUtils.getConnection()
|
||||
.search(ldapUtils.getBaseDN(), "(&(objectClass=organizationalUnit)(description="+organization.getpId()+"))", constraints);
|
||||
.search(ldapUtils.getBaseDN(), "(&(objectClass=organizationalUnit)(description="+organization.getParentId()+"))", constraints);
|
||||
String rdn="";
|
||||
if (results == null || !results.hasMore()) {
|
||||
rdn=ldapUtils.getBaseDN();
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.maxkey.constants;
|
||||
|
||||
public class ContentType {
|
||||
|
||||
public static final String TEXT_PLAIN = "text/plain";
|
||||
|
||||
public static final String TEXT_PLAIN_UTF8 = "text/plain;charset=UTF-8";
|
||||
|
||||
public static final String TEXT_XML = "text/xml";
|
||||
|
||||
public static final String TEXT_XML_UTF8 = "text/xml;charset=UTF-8";
|
||||
|
||||
public static final String APPLICATION_JSON = "application/json";
|
||||
|
||||
public static final String APPLICATION_JSON_UTF8 = "application/json;charset=UTF-8";
|
||||
|
||||
public static final String APPLICATION_JWT = "application/jwt";
|
||||
|
||||
public static final String APPLICATION_JWT_UTF8 = "application/jwt;charset=UTF-8";
|
||||
|
||||
public static final String APPLICATION_XML = "application/xml";
|
||||
|
||||
public static final String APPLICATION_XML_UTF8 = "application/xml;charset=UTF-8";
|
||||
|
||||
public static final String IMAGE_GIF = "image/gif";
|
||||
|
||||
public static final String IMAGE_JPEG = "image/jpeg";
|
||||
|
||||
public static final String IMAGE_PNG = "image/png";
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,18 +1,18 @@
|
||||
package org.maxkey.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.apache.mybatis.jpa.persistence.JpaBaseDomain;
|
||||
|
||||
@Table(name = "ORGANIZATIONS")
|
||||
public class Organizations extends JpaBaseDomain implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 5085413816404119803L;
|
||||
|
||||
@Id
|
||||
@Column
|
||||
@GeneratedValue(strategy = GenerationType.AUTO, generator = "uuid")
|
||||
@@ -24,15 +24,15 @@ public class Organizations extends JpaBaseDomain implements Serializable {
|
||||
@Column
|
||||
private String fullName;
|
||||
@Column
|
||||
private String pId;
|
||||
private String parentId;
|
||||
@Column
|
||||
private String pName;
|
||||
private String parentName;
|
||||
@Column
|
||||
private String type;
|
||||
@Column
|
||||
private String xPath;
|
||||
private String codePath;
|
||||
@Column
|
||||
private String xNamePath;
|
||||
private String namePath;
|
||||
@Column
|
||||
private String level;
|
||||
@Column
|
||||
@@ -60,15 +60,10 @@ public class Organizations extends JpaBaseDomain implements Serializable {
|
||||
@Column
|
||||
private String email;
|
||||
@Column
|
||||
private String sortOrder;
|
||||
private String sortIndex;
|
||||
@Column
|
||||
private String description;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 5085413816404119803L;
|
||||
|
||||
public Organizations() {
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
@@ -105,20 +100,22 @@ public class Organizations extends JpaBaseDomain implements Serializable {
|
||||
this.fullName = fullName;
|
||||
}
|
||||
|
||||
public String getpId() {
|
||||
return pId;
|
||||
|
||||
|
||||
public String getParentId() {
|
||||
return parentId;
|
||||
}
|
||||
|
||||
public void setpId(String pId) {
|
||||
this.pId = pId;
|
||||
public void setParentId(String parentId) {
|
||||
this.parentId = parentId;
|
||||
}
|
||||
|
||||
public String getpName() {
|
||||
return pName;
|
||||
public String getParentName() {
|
||||
return parentName;
|
||||
}
|
||||
|
||||
public void setpName(String pName) {
|
||||
this.pName = pName;
|
||||
public void setParentName(String parentName) {
|
||||
this.parentName = parentName;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
@@ -129,22 +126,6 @@ public class Organizations extends JpaBaseDomain implements Serializable {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getxPath() {
|
||||
return xPath;
|
||||
}
|
||||
|
||||
public void setxPath(String xPath) {
|
||||
this.xPath = xPath;
|
||||
}
|
||||
|
||||
public String getxNamePath() {
|
||||
return xNamePath;
|
||||
}
|
||||
|
||||
public void setxNamePath(String xNamePath) {
|
||||
this.xNamePath = xNamePath;
|
||||
}
|
||||
|
||||
public String getLevel() {
|
||||
return level;
|
||||
}
|
||||
@@ -265,14 +246,41 @@ public class Organizations extends JpaBaseDomain implements Serializable {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Organizations [id=" + id + ", code=" + code + ", name=" + name + ", fullName=" + fullName + ", pId="
|
||||
+ pId + ", pName=" + pName + ", type=" + type + ", xPath=" + xPath + ", xNamePath=" + xNamePath
|
||||
+ ", level=" + level + ", hasChild=" + hasChild + ", division=" + division + ", country=" + country
|
||||
+ ", region=" + region + ", locality=" + locality + ", street=" + street + ", address=" + address
|
||||
+ ", contact=" + contact + ", postalCode=" + postalCode + ", phone=" + phone + ", fax=" + fax
|
||||
+ ", email=" + email + ", sortOrder=" + sortOrder + ", description=" + description + "]";
|
||||
public String getCodePath() {
|
||||
return codePath;
|
||||
}
|
||||
|
||||
public void setCodePath(String codePath) {
|
||||
this.codePath = codePath;
|
||||
}
|
||||
|
||||
public String getNamePath() {
|
||||
return namePath;
|
||||
}
|
||||
|
||||
public void setNamePath(String namePath) {
|
||||
this.namePath = namePath;
|
||||
}
|
||||
|
||||
public String getSortIndex() {
|
||||
return sortIndex;
|
||||
}
|
||||
|
||||
public void setSortIndex(String sortIndex) {
|
||||
this.sortIndex = sortIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Organizations [id=" + id + ", code=" + code + ", name=" + name + ", fullName=" + fullName
|
||||
+ ", parentId=" + parentId + ", parentName=" + parentName + ", type=" + type + ", codePath=" + codePath
|
||||
+ ", namePath=" + namePath + ", level=" + level + ", hasChild=" + hasChild + ", division=" + division
|
||||
+ ", country=" + country + ", region=" + region + ", locality=" + locality + ", street=" + street
|
||||
+ ", address=" + address + ", contact=" + contact + ", postalCode=" + postalCode + ", phone=" + phone
|
||||
+ ", fax=" + fax + ", email=" + email + ", sortIndex=" + sortIndex + ", description=" + description
|
||||
+ "]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,55 +6,45 @@ import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Table(name = "APPS_CAS_DETAILS")
|
||||
@Table(name = "APPS_CAS_DETAILS")
|
||||
public class AppsCasDetails extends Apps {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -4272290765948322084L;
|
||||
@Id
|
||||
@Column
|
||||
@GeneratedValue(strategy=GenerationType.AUTO,generator="uuid")
|
||||
private String id;
|
||||
@Column
|
||||
private String service;
|
||||
@Column
|
||||
private String validation;
|
||||
|
||||
/**
|
||||
* @return the service
|
||||
*/
|
||||
public String getService() {
|
||||
return service;
|
||||
}
|
||||
/**
|
||||
* @param service the service to set
|
||||
*/
|
||||
public void setService(String service) {
|
||||
this.service = service;
|
||||
}
|
||||
/**
|
||||
* @return the validation
|
||||
*/
|
||||
public String getValidation() {
|
||||
return validation;
|
||||
}
|
||||
/**
|
||||
* @param validation the validation to set
|
||||
*/
|
||||
public void setValidation(String validation) {
|
||||
this.validation = validation;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CASDetails [service=" + service + ", validation=" + validation
|
||||
+ "]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -4272290765948322084L;
|
||||
@Id
|
||||
@Column
|
||||
@GeneratedValue(strategy = GenerationType.AUTO, generator = "uuid")
|
||||
private String id;
|
||||
@Column
|
||||
private String service;
|
||||
@Column
|
||||
private String callbackUrl;
|
||||
|
||||
/**
|
||||
* @return the service
|
||||
*/
|
||||
public String getService() {
|
||||
return service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param service the service to set
|
||||
*/
|
||||
public void setService(String service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public String getCallbackUrl() {
|
||||
return callbackUrl;
|
||||
}
|
||||
|
||||
public void setCallbackUrl(String callbackUrl) {
|
||||
this.callbackUrl = callbackUrl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -77,13 +77,13 @@ public class AppsSAML20Details extends Apps {
|
||||
@Column
|
||||
private int nameIdConvert;
|
||||
|
||||
public static class BINDINGTYPE {
|
||||
public String Redirect_Post = "Redirect-Post";
|
||||
public String Post_Post = "Post-Post";
|
||||
public String IdpInit_Post = "IdpInit-Post";
|
||||
public String Redirect_PostSimpleSign = "Redirect-PostSimpleSign";
|
||||
public String Post_PostSimpleSign = "Post-PostSimpleSign";
|
||||
public String IdpInit_PostSimpleSign = "IdpInit-PostSimpleSign";
|
||||
public static final class BindingType {
|
||||
public static final String Redirect_Post = "Redirect-Post";
|
||||
public static final String Post_Post = "Post-Post";
|
||||
public static final String IdpInit_Post = "IdpInit-Post";
|
||||
public static final String Redirect_PostSimpleSign = "Redirect-PostSimpleSign";
|
||||
public static final String Post_PostSimpleSign = "Post-PostSimpleSign";
|
||||
public static final String IdpInit_PostSimpleSign = "IdpInit-PostSimpleSign";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,6 +10,7 @@ import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.maxkey.configuration.ApplicationConfig;
|
||||
import org.maxkey.constants.ContentType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -48,7 +49,7 @@ public class AbstractImageEndpoint {
|
||||
// Set standard HTTP/1.0 no-cache header.
|
||||
response.setHeader("Pragma", "no-cache");
|
||||
// return a jpeg/gif
|
||||
response.setContentType("image/gif");
|
||||
response.setContentType(ContentType.IMAGE_GIF);
|
||||
_logger.trace("create the image");
|
||||
// create the image
|
||||
if (bufferedImage != null) {
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
<if test="name != null and name != '' ">
|
||||
AND NAME like '%#{name}%'
|
||||
</if>
|
||||
<if test="pId != null and pId != '' ">
|
||||
AND PID = #{pId}
|
||||
<if test="parentId != null and parentId != '' ">
|
||||
AND PARENTID = #{parentId}
|
||||
</if>
|
||||
<if test="pName != null and pName != ''">
|
||||
AND PNAME like '%#{pName}%'
|
||||
<if test="parentName != null and parentName != ''">
|
||||
AND PARENTNAME like '%#{parentName}%'
|
||||
</if>
|
||||
|
||||
</sql>
|
||||
@@ -41,8 +41,8 @@
|
||||
<if test="enable != null">
|
||||
ADN STATUS = '1'
|
||||
</if>
|
||||
<if test="xPath != null">
|
||||
ADN XPATH = #{xPath}
|
||||
<if test="codePath != null">
|
||||
ADN CODEPATH = #{codePath}
|
||||
</if>
|
||||
</update>
|
||||
|
||||
|
||||
@@ -94,6 +94,17 @@ public class CasAuthorizeEndpoint extends AuthorizeBaseEndpoint{
|
||||
|
||||
String ticket=ticketServices.createTicket(serviceTicket);
|
||||
|
||||
return WebContext.redirect(casDetails.getService()+"?"+CasConstants.PARAMETER.TICKET+"="+ticket);
|
||||
StringBuffer callbackUrl = new StringBuffer(casDetails.getCallbackUrl());
|
||||
if(casDetails.getCallbackUrl().indexOf("?")==-1) {
|
||||
callbackUrl.append("?");
|
||||
}
|
||||
|
||||
callbackUrl.append(CasConstants.PARAMETER.TICKET).append("=").append(ticket)
|
||||
.append("&")
|
||||
.append(CasConstants.PARAMETER.SERVICE).append("=").append(casDetails.getService());
|
||||
|
||||
_logger.debug("redirect to CAS Client URL " + callbackUrl);
|
||||
|
||||
return WebContext.redirect(callbackUrl.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import java.util.HashMap;
|
||||
|
||||
import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.util.DateUtils;
|
||||
import org.maxkey.util.JsonUtils;
|
||||
import org.maxkey.util.StringGenerator;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
@@ -6,12 +6,16 @@ import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter;
|
||||
import org.maxkey.authz.oauth2.common.exceptions.OAuth2Exception;
|
||||
import org.maxkey.authz.oauth2.provider.ClientDetailsService;
|
||||
import org.maxkey.authz.oauth2.provider.OAuth2Authentication;
|
||||
import org.maxkey.authz.oauth2.provider.token.DefaultTokenServices;
|
||||
import org.maxkey.constants.Boolean;
|
||||
import org.maxkey.constants.ContentType;
|
||||
import org.maxkey.crypto.ReciprocalUtils;
|
||||
import org.maxkey.crypto.jwt.encryption.service.JwtEncryptionAndDecryptionService;
|
||||
import org.maxkey.crypto.jwt.encryption.service.impl.RecipientJwtEncryptionAndDecryptionServiceBuilder;
|
||||
@@ -76,6 +80,7 @@ public class UserInfoEndpoint {
|
||||
@Qualifier("jwtEncryptionService")
|
||||
private JwtEncryptionAndDecryptionService jwtEnDecryptionService;
|
||||
|
||||
|
||||
private SymmetricSigningAndValidationServiceBuilder symmetricJwtSignerServiceBuilder
|
||||
=new SymmetricSigningAndValidationServiceBuilder();
|
||||
|
||||
@@ -85,13 +90,16 @@ public class UserInfoEndpoint {
|
||||
|
||||
OAuthDefaultUserInfoAdapter defaultOAuthUserInfoAdapter=new OAuthDefaultUserInfoAdapter();
|
||||
|
||||
@RequestMapping(value="/oauth/v20/me",produces="text/plain;charset=UTF-8")
|
||||
@RequestMapping(value="/oauth/v20/me")
|
||||
@ResponseBody
|
||||
public String apiV20UserInfo(
|
||||
@RequestParam(value = "access_token", required = true) String access_token) {
|
||||
@RequestParam(value = "access_token", required = true) String access_token,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
response.setContentType(ContentType.APPLICATION_JSON_UTF8);
|
||||
String principal="";
|
||||
if (!StringGenerator.uuidMatches(access_token)) {
|
||||
return accessTokenFormatError(access_token);
|
||||
return JsonUtils.gson2Json(accessTokenFormatError(access_token));
|
||||
}
|
||||
OAuth2Authentication oAuth2Authentication =null;
|
||||
try{
|
||||
@@ -103,8 +111,6 @@ public class UserInfoEndpoint {
|
||||
UserInfo userInfo=queryUserInfo(principal);
|
||||
Apps app=appsService.get(client_id);
|
||||
|
||||
String userJson="";
|
||||
|
||||
AbstractAuthorizeAdapter adapter;
|
||||
if(Boolean.isTrue(app.getIsAdapter())){
|
||||
adapter =(AbstractAuthorizeAdapter)Instance.newInstance(app.getAdapter());
|
||||
@@ -112,28 +118,28 @@ public class UserInfoEndpoint {
|
||||
adapter =(AbstractAuthorizeAdapter)defaultOAuthUserInfoAdapter;
|
||||
}
|
||||
|
||||
String jsonData=adapter.generateInfo(userInfo, null);
|
||||
userJson=adapter.sign(jsonData, app);
|
||||
|
||||
return userJson;
|
||||
|
||||
String jsonData=adapter.generateInfo(userInfo, app);
|
||||
return jsonData;
|
||||
}catch(OAuth2Exception e){
|
||||
HashMap<String,Object>authzException=new HashMap<String,Object>();
|
||||
authzException.put(OAuth2Exception.ERROR, e.getOAuth2ErrorCode());
|
||||
authzException.put(OAuth2Exception.DESCRIPTION,e.getMessage());
|
||||
return JsonUtils.object2Json(authzException);
|
||||
return JsonUtils.gson2Json(authzException);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(value="/connect/v10/userinfo",produces="text/plain;charset=UTF-8")
|
||||
@RequestMapping(value="/connect/v10/userinfo")
|
||||
@ResponseBody
|
||||
public String apiConnect10aUserInfo(
|
||||
@RequestHeader(value = "Authorization", required = true) String access_token) {
|
||||
public String connect10aUserInfo(
|
||||
@RequestHeader(value = "Authorization", required = true) String access_token,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
String principal="";
|
||||
if (!StringGenerator.uuidMatches(access_token)) {
|
||||
return accessTokenFormatError(access_token);
|
||||
return JsonUtils.gson2Json(accessTokenFormatError(access_token));
|
||||
}
|
||||
|
||||
OAuth2Authentication oAuth2Authentication =null;
|
||||
try{
|
||||
oAuth2Authentication = oauth20tokenServices.loadAuthentication(access_token);
|
||||
@@ -207,10 +213,14 @@ public class UserInfoEndpoint {
|
||||
JWTClaimsSet userInfoJWTClaims = jwtClaimsSetBuilder.build();
|
||||
JWT userInfoJWT=null;
|
||||
JWSAlgorithm signingAlg = jwtSignerValidationService.getDefaultSigningAlgorithm();
|
||||
if (clientDetails.getUserInfoEncryptedAlgorithm() != null && !clientDetails.getUserInfoEncryptedAlgorithm().equals("none")
|
||||
&& clientDetails.getUserInfoEncryptionMethod() != null && !clientDetails.getUserInfoEncryptionMethod().equals("none")
|
||||
if (clientDetails.getUserInfoEncryptedAlgorithm() != null
|
||||
&& !clientDetails.getUserInfoEncryptedAlgorithm().equals("none")
|
||||
&& clientDetails.getUserInfoEncryptionMethod() != null
|
||||
&& !clientDetails.getUserInfoEncryptionMethod().equals("none")
|
||||
&&clientDetails.getJwksUri()!=null&&clientDetails.getJwksUri().length()>4
|
||||
) {
|
||||
//需要加密
|
||||
response.setContentType(ContentType.APPLICATION_JWT_UTF8);
|
||||
JwtEncryptionAndDecryptionService recipientJwtEnDecryptionService =
|
||||
recipientJwtEnDecryptionServiceBuilder.serviceBuilder(clientDetails.getJwksUri());
|
||||
|
||||
@@ -227,38 +237,41 @@ public class UserInfoEndpoint {
|
||||
authzException.put(OAuth2Exception.DESCRIPTION,"Couldn't find encrypter for client: " + clientDetails.getClientId());
|
||||
return JsonUtils.gson2Json(authzException);
|
||||
}
|
||||
} else {
|
||||
if (clientDetails.getUserInfoSigningAlgorithm()==null||clientDetails.getUserInfoSigningAlgorithm().equals("none")) {
|
||||
// unsigned ID token
|
||||
//userInfoJWT = new PlainJWT(userInfoJWTClaims);
|
||||
userJson=JsonUtils.gson2Json(jwtClaimsSetBuilder.getClaims());
|
||||
} else {
|
||||
// signed ID token
|
||||
if (signingAlg.equals(JWSAlgorithm.HS256)
|
||||
|| signingAlg.equals(JWSAlgorithm.HS384)
|
||||
|| signingAlg.equals(JWSAlgorithm.HS512)) {
|
||||
// sign it with the client's secret
|
||||
String client_secret=ReciprocalUtils.decoder(clientDetails.getClientSecret());
|
||||
|
||||
JwtSigningAndValidationService symmetricJwtSignerService =symmetricJwtSignerServiceBuilder.serviceBuilder(client_secret);
|
||||
if(symmetricJwtSignerService!=null){
|
||||
userInfoJWTClaims = new JWTClaimsSet.Builder(userInfoJWTClaims).claim("kid", "SYMMETRIC-KEY").build();
|
||||
userInfoJWT = new SignedJWT(new JWSHeader(signingAlg), userInfoJWTClaims);
|
||||
symmetricJwtSignerService.signJwt((SignedJWT) userInfoJWT);
|
||||
}else{
|
||||
_logger.error("Couldn't create symmetric validator for client " + clientDetails.getClientId() + " without a client secret");
|
||||
}
|
||||
} else {
|
||||
userInfoJWTClaims = new JWTClaimsSet.Builder(userInfoJWTClaims).claim("kid", jwtSignerValidationService.getDefaultSignerKeyId()).build();
|
||||
}else if (clientDetails.getUserInfoSigningAlgorithm()!=null
|
||||
&& !clientDetails.getUserInfoSigningAlgorithm().equals("none")) {
|
||||
//需要签名
|
||||
response.setContentType(ContentType.APPLICATION_JWT_UTF8);
|
||||
// signed ID token
|
||||
if (signingAlg.equals(JWSAlgorithm.HS256)
|
||||
|| signingAlg.equals(JWSAlgorithm.HS384)
|
||||
|| signingAlg.equals(JWSAlgorithm.HS512)) {
|
||||
// sign it with the client's secret
|
||||
String client_secret=ReciprocalUtils.decoder(clientDetails.getClientSecret());
|
||||
|
||||
JwtSigningAndValidationService symmetricJwtSignerService =symmetricJwtSignerServiceBuilder.serviceBuilder(client_secret);
|
||||
if(symmetricJwtSignerService!=null){
|
||||
userInfoJWTClaims = new JWTClaimsSet.Builder(userInfoJWTClaims).claim("kid", "SYMMETRIC-KEY").build();
|
||||
userInfoJWT = new SignedJWT(new JWSHeader(signingAlg), userInfoJWTClaims);
|
||||
// sign it with the server's key
|
||||
jwtSignerValidationService.signJwt((SignedJWT) userInfoJWT);
|
||||
symmetricJwtSignerService.signJwt((SignedJWT) userInfoJWT);
|
||||
}else{
|
||||
_logger.error("Couldn't create symmetric validator for client " + clientDetails.getClientId() + " without a client secret");
|
||||
}
|
||||
userJson=userInfoJWT.serialize();
|
||||
} else {
|
||||
userInfoJWTClaims = new JWTClaimsSet.Builder(userInfoJWTClaims).claim("kid", jwtSignerValidationService.getDefaultSignerKeyId()).build();
|
||||
userInfoJWT = new SignedJWT(new JWSHeader(signingAlg), userInfoJWTClaims);
|
||||
// sign it with the server's key
|
||||
jwtSignerValidationService.signJwt((SignedJWT) userInfoJWT);
|
||||
}
|
||||
}
|
||||
userJson=userInfoJWT.serialize();
|
||||
}else {
|
||||
//不需要加密和签名
|
||||
response.setContentType(ContentType.APPLICATION_JSON_UTF8);
|
||||
// unsigned ID token
|
||||
//userInfoJWT = new PlainJWT(userInfoJWTClaims);
|
||||
userJson=JsonUtils.gson2Json(jwtClaimsSetBuilder.getClaims());
|
||||
}
|
||||
|
||||
return userJson;
|
||||
return userJson;
|
||||
|
||||
}catch(OAuth2Exception e){
|
||||
HashMap<String,Object>authzException=new HashMap<String,Object>();
|
||||
@@ -267,17 +280,15 @@ public class UserInfoEndpoint {
|
||||
return JsonUtils.object2Json(authzException);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String accessTokenFormatError(String access_token){
|
||||
|
||||
public HashMap<String,Object> accessTokenFormatError(String access_token){
|
||||
HashMap<String,Object>atfe=new HashMap<String,Object>();
|
||||
atfe.put(OAuth2Exception.ERROR, "token Format Invalid");
|
||||
atfe.put(OAuth2Exception.DESCRIPTION, "access Token Format Invalid , access_token : "+access_token);
|
||||
|
||||
return JsonUtils.object2Json(atfe);
|
||||
return atfe;
|
||||
}
|
||||
|
||||
|
||||
public UserInfo queryUserInfo(String uid){
|
||||
_logger.debug("uid : "+uid);
|
||||
UserInfo userInfo = (UserInfo) userInfoService.loadByUsername(uid);
|
||||
|
||||
@@ -48,7 +48,7 @@ public class OrganizationsController {
|
||||
}
|
||||
|
||||
treeNode.setAttr("data", org);
|
||||
treeNode.setPId(org.getpId());
|
||||
treeNode.setPId(org.getParentId());
|
||||
if (org.getId().equals("1")) {
|
||||
treeNode.setAttr("open", Boolean.valueOf(true));
|
||||
} else {
|
||||
|
||||
@@ -12,7 +12,7 @@ config.maxkey.uri=${config.server.name}/maxkey
|
||||
#InMemory 0 , jdbc 1, Redis 2
|
||||
config.server.persistence=0
|
||||
#identity
|
||||
config.identity.kafkasupport=true
|
||||
config.identity.kafkasupport=false
|
||||
############################################################################
|
||||
# Login configuration
|
||||
#enable captcha
|
||||
@@ -62,7 +62,7 @@ config.saml.v20.sp.keystore=classpath\:config/samlClientKeystore.jks
|
||||
config.saml.v20.sp.issuing.entity.id=client.maxkey.org
|
||||
|
||||
############################################################################
|
||||
config.oidc.metadata.issuer=${config.server.name}/maxkey
|
||||
config.oidc.metadata.issuer=https://${config.server.domain.sub}/maxkey
|
||||
config.oidc.metadata.authorizationEndpoint=${config.server.name}/maxkey/oauth/v20/authorize
|
||||
config.oidc.metadata.tokenEndpoint=${config.server.name}/maxkey/oauth/v20/token
|
||||
config.oidc.metadata.userinfoEndpoint=${config.server.name}/maxkey/api/connect/userinfo
|
||||
|
||||
@@ -298,8 +298,8 @@ apps.formbased.parameter=\u53C2\u6570
|
||||
apps.formbased.parameter.value=\u53C2\u6570\u503C
|
||||
#cas
|
||||
apps.cas.info=CAS\u8BA4\u8BC1
|
||||
apps.cas.service=\u670D\u52A1\u5730\u5740
|
||||
apps.cas.validation=\u9A8C\u8BC1\u5730\u5740
|
||||
apps.cas.service=\u670D\u52A1
|
||||
apps.cas.callbackUrl=\u56DE\u8C03\u5730\u5740
|
||||
#desktop
|
||||
apps.desktop.info=\u684C\u9762\u8BA4\u8BC1
|
||||
apps.desktop.programPath=\u5E94\u7528\u5B89\u88C5\u8DEF\u5F84
|
||||
|
||||
@@ -298,7 +298,7 @@ apps.formbased.authorizeView=authorizeView
|
||||
#cas
|
||||
apps.cas.info=CAS Info
|
||||
apps.cas.service=service
|
||||
apps.cas.validation=validation
|
||||
apps.cas.callbackUrl=CallbackUrl
|
||||
#desktop
|
||||
apps.desktop.info=Desktop Info
|
||||
apps.desktop.programPath=programPath
|
||||
|
||||
@@ -298,8 +298,8 @@ apps.formbased.parameter=\u53C2\u6570
|
||||
apps.formbased.parameter.value=\u53C2\u6570\u503C
|
||||
#cas
|
||||
apps.cas.info=CAS\u8BA4\u8BC1
|
||||
apps.cas.service=\u670D\u52A1\u5730\u5740
|
||||
apps.cas.validation=\u9A8C\u8BC1\u5730\u5740
|
||||
apps.cas.service=\u670D\u52A1
|
||||
apps.cas.callbackUrl=\u56DE\u8C03\u5730\u5740
|
||||
#desktop
|
||||
apps.desktop.info=\u684C\u9762\u8BA4\u8BC1
|
||||
apps.desktop.programPath=\u5E94\u7528\u5B89\u88C5\u8DEF\u5F84
|
||||
|
||||
@@ -52,9 +52,9 @@ $(function(){
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th style="width:15%;"><@locale code="apps.cas.validation"/>:</th>
|
||||
<th style="width:15%;"><@locale code="apps.cas.callbackUrl"/>:</th>
|
||||
<td colspan=3>
|
||||
<input type="text" class="form-control" id="validation" name="validation" title="" value="" required="" />
|
||||
<input type="text" class="form-control" id="callbackUrl" name="callbackUrl" title="" value="" required="" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -62,9 +62,9 @@ $(function(){
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th style="width:15%;"><@locale code="apps.cas.validation"/>:</th>
|
||||
<th style="width:15%;"><@locale code="apps.cas.callbackUrl"/>:</th>
|
||||
<td colspan=3>
|
||||
<input type="text" class="form-control" id="redirectUri" name="validation" title="" value="${model.validation}" required="" />
|
||||
<input type="text" class="form-control" id="callbackUrl" name="callbackUrl" title="" value="${model.callbackUrl}" required="" />
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -39,11 +39,11 @@ $(function () {
|
||||
</tr>
|
||||
<tr >
|
||||
<td > <@locale code="org.pid" />:</td>
|
||||
<td><input type="text" id="pId" name="pId" class="form-control"/></td>
|
||||
<td><input type="text" id="pId" name="parentId" class="form-control"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th width="200px"> <@locale code="org.pname" />:</td>
|
||||
<td><input type="text" id="pName" name="pName" class="form-control"/></td>
|
||||
<td><input type="text" id="pName" name="parentName" class="form-control"/></td>
|
||||
</tr>
|
||||
<tr >
|
||||
<td > <@locale code="org.id" />:</td>
|
||||
@@ -60,13 +60,13 @@ $(function () {
|
||||
<tr >
|
||||
<td > <@locale code="org.xpath" /> :
|
||||
</th>
|
||||
<td><input type="text" id="xPath" name="xPath" class="form-control"/></td>
|
||||
<td><input type="text" id="xPath" name="codePath" class="form-control"/></td>
|
||||
</tr>
|
||||
|
||||
<tr >
|
||||
<td > <@locale code="org.xnamepath" /> :
|
||||
</th>
|
||||
<td><input type="text" id="xNamePath" name="xNamePath" class="form-control"/></td>
|
||||
<td><input type="text" id="xNamePath" name="namePath" class="form-control"/></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -81,7 +81,7 @@ $(function () {
|
||||
<th >
|
||||
<@locale code="org.sortorder" /> :
|
||||
</th>
|
||||
<td><input type="text" id="sortOrder" name="sortOrder" class="form-control" value='1'/></td>
|
||||
<td><input type="text" id="sortIndex" name="sortIndex" class="form-control" value='1'/></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
@@ -177,7 +177,7 @@ $(function () {
|
||||
<td width="375px">
|
||||
<form id="basic_search_form">
|
||||
<input class="form-control" name="name" type="text" style ="width:150px;float:left;">
|
||||
<input id="pId" class="form-control" name="pId" type="hidden" style ="width:150px;float:left;">
|
||||
<input id="pId" class="form-control" name="parentId" type="hidden" style ="width:150px;float:left;">
|
||||
<input class="button btn btn-primary mr-3" id="searchBtn" type="button" size="50" value="<@locale code="button.text.search"/>">
|
||||
<input class="button btn btn-secondary" id="advancedSearchExpandBtn" type="button" size="50" value="<@locale code="button.text.expandsearch"/>" expandValue="<@locale code="button.text.expandsearch"/>" collapseValue="<@locale code="button.text.collapsesearch"/>">
|
||||
</form>
|
||||
|
||||
@@ -38,11 +38,11 @@ $(function () {
|
||||
</tr>
|
||||
<tr >
|
||||
<td > <@locale code="org.pid" />:</td>
|
||||
<td><input type="text" readonly id="pId" name="pId" class="form-control" value="${model.pId!}"/></td>
|
||||
<td><input type="text" readonly id="pId" name="parentId" class="form-control" value="${model.parentId!}"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th width="200px"> <@locale code="org.pname" />:</td>
|
||||
<td><input type="text" readonly id="pName" name="pName" class="form-control" value="${model.pName!}"/></td>
|
||||
<td><input type="text" readonly id="pName" name="parentName" class="form-control" value="${model.parentName!}"/></td>
|
||||
</tr>
|
||||
<tr >
|
||||
<td > <@locale code="org.id" />:</td>
|
||||
@@ -59,13 +59,13 @@ $(function () {
|
||||
<tr >
|
||||
<td > <@locale code="org.xpath" /> :
|
||||
</th>
|
||||
<td><input type="text" id="xPath" name="xPath" class="form-control" value="${model.xPath!}"/></td>
|
||||
<td><input type="text" id="xPath" name="codePath" class="form-control" value="${model.codePath!}"/></td>
|
||||
</tr>
|
||||
|
||||
<tr >
|
||||
<td > <@locale code="org.xnamepath" /> :
|
||||
</th>
|
||||
<td><input type="text" id="xNamePath" name="xNamePath" class="form-control" value="${model.xNamePath!}"/></td>
|
||||
<td><input type="text" id="xNamePath" name="namePath" class="form-control" value="${model.namePath!}"/></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -80,7 +80,7 @@ $(function () {
|
||||
<th >
|
||||
<@locale code="org.sortorder" /> :
|
||||
</th>
|
||||
<td><input type="text" id="sortOrder" name="sortOrder" class="form-control" value="${model.sortOrder!}"/></td>
|
||||
<td><input type="text" id="sortOrder" name="sortIndex" class="form-control" value="${model.sortIndex!}"/></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
# domain name configuration
|
||||
config.server.domain=maxkey.top
|
||||
config.server.domain.sub=sso.${config.server.domain}
|
||||
config.server.name=http://${config.server.domain.sub}
|
||||
config.server.prefix.uri=${config.server.name}:80/maxkey
|
||||
config.server.name=https://${config.server.domain.sub}
|
||||
config.server.prefix.uri=${config.server.name}/maxkey
|
||||
#default.uri
|
||||
config.server.default.uri=${config.server.prefix.uri}/maxkey/appList
|
||||
config.server.management.uri=${config.server.name}:9521/maxkey-mgt/login
|
||||
|
||||
Reference in New Issue
Block a user