v2.0.0GA
This commit is contained in:
shimingxy
2020-07-04 09:43:15 +08:00
parent 585397b926
commit ca3d6e036b
26 changed files with 730 additions and 797 deletions

View File

@@ -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
企业微信支持
钉钉支持
动态用户组实现(基于用户属性或机构)

View File

@@ -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) 登录错误修复

View File

@@ -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'
}

View File

@@ -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();

View File

@@ -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();

View File

@@ -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";
}

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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";
}
/**

View File

@@ -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) {

View File

@@ -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>

View File

@@ -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());
}
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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 {

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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