diff --git a/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/web/AuthEntryPoint.java b/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/web/AuthEntryPoint.java new file mode 100644 index 0000000000000000000000000000000000000000..400bd98d2d0c2f2572be85fddfec0c9251fd32ed --- /dev/null +++ b/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/web/AuthEntryPoint.java @@ -0,0 +1,41 @@ +package org.maxkey.authn.web; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +import com.fasterxml.jackson.core.exc.StreamWriteException; +import com.fasterxml.jackson.databind.DatabindException; +import com.fasterxml.jackson.databind.ObjectMapper; + +@Controller +public class AuthEntryPoint { + private static final Logger _logger = LoggerFactory.getLogger(AuthEntryPoint.class); + + @RequestMapping(value={"/auth/entrypoint"}) + public void entryPoint( + HttpServletRequest request, HttpServletResponse response) + throws StreamWriteException, DatabindException, IOException { + _logger.trace("AuthEntryPoint /entrypoint."); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + + final Map body = new HashMap<>(); + body.put("status", HttpServletResponse.SC_UNAUTHORIZED); + body.put("error", "Unauthorized"); + body.put("message", "Unauthorized"); + body.put("path", request.getServletPath()); + + final ObjectMapper mapper = new ObjectMapper(); + mapper.writeValue(response.getOutputStream(), body); + } +} diff --git a/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/web/interceptor/PermissionAdapter.java b/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/web/interceptor/PermissionAdapter.java index b52df56bf267d413bcc57d748252e1c822f5ac55..1caca36034d684cd4a1f6d18c63873073fff27d3 100644 --- a/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/web/interceptor/PermissionAdapter.java +++ b/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/web/interceptor/PermissionAdapter.java @@ -78,8 +78,8 @@ public class PermissionAdapter implements AsyncHandlerInterceptor { //判断用户是否登录 if(WebContext.getAuthentication()==null ||WebContext.getAuthentication().getAuthorities()==null){//判断用户和角色,判断用户是否登录用户 - _logger.trace("No Authentication ... forward to /login"); - RequestDispatcher dispatcher = request.getRequestDispatcher("/login"); + _logger.trace("No Authentication ... forward to /auth/entrypoint"); + RequestDispatcher dispatcher = request.getRequestDispatcher("/auth/entrypoint"); dispatcher.forward(request, response); return false; } diff --git a/maxkey-core/src/main/java/org/maxkey/constants/ConstsBoolean.java b/maxkey-core/src/main/java/org/maxkey/constants/ConstsBoolean.java index c9dea1a427300f31b9f2836fa722e8c15020c0e7..50b1c861d96a281a50318d5a68310db74e0d5b99 100644 --- a/maxkey-core/src/main/java/org/maxkey/constants/ConstsBoolean.java +++ b/maxkey-core/src/main/java/org/maxkey/constants/ConstsBoolean.java @@ -50,6 +50,10 @@ public class ConstsBoolean { public static boolean isTrue(int value) { return TRUE == value; } + + public static boolean isYes(String value) { + return "YES" == value.toUpperCase(); + } public static boolean isFalse(int value) { return FALSE == value; diff --git a/maxkey-core/src/main/java/org/maxkey/entity/apps/AppsOAuth20Details.java b/maxkey-core/src/main/java/org/maxkey/entity/apps/AppsOAuth20Details.java index 5c987bc97cd455475302b13e45efc87c60f535b0..fc4ef04ad3fbef152d26c70bc236fd860be7fdbf 100644 --- a/maxkey-core/src/main/java/org/maxkey/entity/apps/AppsOAuth20Details.java +++ b/maxkey-core/src/main/java/org/maxkey/entity/apps/AppsOAuth20Details.java @@ -108,12 +108,16 @@ public class AppsOAuth20Details extends Apps { this.setAdapterName(application.getAdapterName()); this.clientSecret = baseClientDetails.getClientSecret(); - this.scope = baseClientDetails.getScope().toString(); - this.resourceIds = baseClientDetails.getResourceIds().toString(); - this.authorizedGrantTypes = baseClientDetails.getAuthorizedGrantTypes().toString(); + this.scope = StringUtils + .collectionToCommaDelimitedString(baseClientDetails.getScope()); + this.resourceIds = StringUtils + .collectionToCommaDelimitedString(baseClientDetails.getResourceIds()); + this.authorizedGrantTypes = StringUtils + .collectionToCommaDelimitedString(baseClientDetails.getAuthorizedGrantTypes()); this.registeredRedirectUris = StringUtils .collectionToCommaDelimitedString(baseClientDetails.getRegisteredRedirectUri()); - this.authorities = baseClientDetails.getAuthorities().toString(); + this.authorities = StringUtils + .collectionToCommaDelimitedString(baseClientDetails.getAuthorities()); this.accessTokenValiditySeconds = baseClientDetails.getAccessTokenValiditySeconds(); this.refreshTokenValiditySeconds = baseClientDetails.getRefreshTokenValiditySeconds(); this.approvalPrompt = baseClientDetails.isAutoApprove("all") + ""; diff --git a/maxkey-core/src/main/java/org/maxkey/entity/apps/AppsSAML20Details.java b/maxkey-core/src/main/java/org/maxkey/entity/apps/AppsSAML20Details.java index 2b7aaf73eb130309175cca5f3294959ad6908b06..d6c4b4a7c8cce27b770d684ce559c2d41ace44d9 100644 --- a/maxkey-core/src/main/java/org/maxkey/entity/apps/AppsSAML20Details.java +++ b/maxkey-core/src/main/java/org/maxkey/entity/apps/AppsSAML20Details.java @@ -26,8 +26,6 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; -import org.springframework.web.multipart.MultipartFile; - /** * @author Crystal.Sea * @@ -79,17 +77,14 @@ public class AppsSAML20Details extends Apps { * 0 false 1 true */ @Column - private int encrypted; - - /** - * for upload - */ - private MultipartFile metaFile; + private String encrypted; /** * metadata_file metadata_url or certificate */ private String fileType; + String metaFileId; + X509Certificate trustCert = null; /** * metadata Url @@ -101,7 +96,7 @@ public class AppsSAML20Details extends Apps { * 0 original 1 uppercase 2 lowercase */ @Column - private int nameIdConvert; + private String nameIdConvert; @Column private String nameIdSuffix; @@ -283,15 +278,7 @@ public class AppsSAML20Details extends Apps { this.validityInterval = validityInterval; } - - - public MultipartFile getMetaFile() { - return metaFile; - } - - public void setMetaFile(MultipartFile metaFile) { - this.metaFile = metaFile; - } + /** * @return the fileType @@ -307,7 +294,15 @@ public class AppsSAML20Details extends Apps { this.fileType = fileType; } - public String getBinding() { + public String getMetaFileId() { + return metaFileId; + } + + public void setMetaFileId(String metaFileId) { + this.metaFileId = metaFileId; + } + + public String getBinding() { return binding; } @@ -315,19 +310,19 @@ public class AppsSAML20Details extends Apps { this.binding = binding; } - public int getEncrypted() { + public String getEncrypted() { return encrypted; } - public void setEncrypted(int encrypted) { + public void setEncrypted(String encrypted) { this.encrypted = encrypted; } - public int getNameIdConvert() { + public String getNameIdConvert() { return nameIdConvert; } - public void setNameIdConvert(int nameIdConvert) { + public void setNameIdConvert(String nameIdConvert) { this.nameIdConvert = nameIdConvert; } diff --git a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/AuthnResponseGenerator.java b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/AuthnResponseGenerator.java index e487eec9a26d7c5ef155387d9f6d1baeae5b17ba..c35fd4c4dc6a990b650778e77984187f85aff343 100644 --- a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/AuthnResponseGenerator.java +++ b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/AuthnResponseGenerator.java @@ -78,7 +78,7 @@ public class AuthnResponseGenerator { attributeMap); //Encrypt - if(ConstsBoolean.isTrue(saml20Details.getEncrypted())) { + if(ConstsBoolean.isYes(saml20Details.getEncrypted())) { logger.info("begin to encrypt assertion"); try { // Assume this contains a recipient's RSA public diff --git a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/SubjectGenerator.java b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/SubjectGenerator.java index f9789044728c93129699a9f14ede0af91893c544..dbd9dfdd188aecfec1b60a7828297fc459602255 100644 --- a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/SubjectGenerator.java +++ b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/xml/SubjectGenerator.java @@ -84,12 +84,12 @@ public class SubjectGenerator { nameIdValue = nameIdValue + saml20Details.getNameIdSuffix(); } - if(saml20Details.getNameIdConvert()==0) { - - }else if(saml20Details.getNameIdConvert()==1) { + if(saml20Details.getNameIdConvert().equalsIgnoreCase("uppercase")) { nameIdValue = nameIdValue.toUpperCase(); - }else if(saml20Details.getNameIdConvert()==1) { + }else if(saml20Details.getNameIdConvert().equalsIgnoreCase("lowercase")) { nameIdValue = nameIdValue.toLowerCase(); + }else { + //do nothing } NameID nameID =builderNameID(nameIdValue,assertionConsumerURL); diff --git a/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/SAML20DetailsController.java b/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/SAML20DetailsController.java index a14f9205b1f08ff2633c91cae4af96a94160230b..cffc350625cc4fdff8778663a0b5a2d538801a0f 100644 --- a/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/SAML20DetailsController.java +++ b/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/SAML20DetailsController.java @@ -17,10 +17,13 @@ package org.maxkey.web.apps.contorller; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.security.KeyStore; import java.security.cert.X509Certificate; + +import org.apache.commons.lang3.StringUtils; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.CloseableHttpClient; @@ -83,7 +86,6 @@ public class SAML20DetailsController extends BaseAppContorller { AppsSAML20Details saml20Details=saml20DetailsService.getAppDetails(id , false); decoderSecret(saml20Details); saml20Details.transIconBase64(); - //modelAndView.addObject("model",saml20Details); //modelAndView.addObject("authzURI",applicationConfig.getAuthzUri()); return new Message(saml20Details).buildResponse(); } @@ -142,60 +144,57 @@ public class SAML20DetailsController extends BaseAppContorller { } } - ////////////////////////////// - - - protected AppsSAML20Details transform(AppsSAML20Details samlDetails) throws Exception{ - super.transform(samlDetails); - if(null==samlDetails.getFileType()||samlDetails.getFileType().equals("certificate")){//certificate file - try { - if (null!=samlDetails.getMetaFile()&&!samlDetails.getMetaFile().isEmpty()) { - InputStream isCert = samlDetails.getMetaFile().getInputStream(); - X509Certificate trustCert = X509CertUtils.loadCertFromInputStream(isCert); - samlDetails.setTrustCert(trustCert); - isCert.close(); - } - } catch (IOException e) { - _logger.error("read certificate file error .", e); - throw new Exception("read certificate file error", e); + if(StringUtils.isNotBlank(samlDetails.getFileType())){ + if(StringUtils.isNotBlank(samlDetails.getMetaFileId())) { + ByteArrayInputStream bArrayInputStream = new ByteArrayInputStream( + fileUploadService.get(samlDetails.getMetaFileId()).getUploaded());; + if(samlDetails.getFileType().equals("certificate")){//certificate file + try { + X509Certificate trustCert = X509CertUtils.loadCertFromInputStream(bArrayInputStream); + samlDetails.setTrustCert(trustCert); + } catch (IOException e) { + _logger.error("read certificate file error .", e); + throw new Exception("read certificate file error", e); + } + }else if(samlDetails.getFileType().equals("metadata_file")){//metadata file + samlDetails = resolveMetaData(samlDetails,bArrayInputStream); + } + } + + if(samlDetails.getFileType().equals("metadata_url") + &&StringUtils.isNotBlank(samlDetails.getMetaUrl())){//metadata url + CloseableHttpClient httpClient = HttpClients.createDefault(); + HttpPost post = new HttpPost(samlDetails.getMetaUrl()); + CloseableHttpResponse response = httpClient.execute(post); + samlDetails = resolveMetaData(samlDetails,response.getEntity().getContent());; + response.close(); + httpClient.close(); + } + + if(samlDetails.getTrustCert()!=null) { + samlDetails.setCertSubject(samlDetails.getTrustCert().getSubjectDN().getName()); + samlDetails.setCertExpiration(samlDetails.getTrustCert().getNotAfter().toString()); + + samlDetails.setCertIssuer(X509CertUtils.getCommonName(samlDetails.getTrustCert().getIssuerX500Principal())); + + KeyStore keyStore = KeyStoreUtil.clone(idpKeyStoreLoader.getKeyStore(),idpKeyStoreLoader.getKeystorePassword()); + + KeyStore trustKeyStore = null; + if (!samlDetails.getEntityId().equals("")) { + trustKeyStore = KeyStoreUtil.importTrustCertificate(keyStore,samlDetails.getTrustCert(), samlDetails.getEntityId()); + } else { + trustKeyStore = KeyStoreUtil.importTrustCertificate(keyStore,samlDetails.getTrustCert()); + } + + byte[] keyStoreByte = KeyStoreUtil.keyStore2Bytes(trustKeyStore,idpKeyStoreLoader.getKeystorePassword()); + + // store KeyStore content + samlDetails.setKeyStore(keyStoreByte); } - }else if(samlDetails.getFileType().equals("metadata_file")){//metadata file - if (null!=samlDetails.getMetaFile()&&!samlDetails.getMetaFile().isEmpty()) { - samlDetails = resolveMetaData(samlDetails,samlDetails.getMetaFile().getInputStream()); - } - }else if(samlDetails.getFileType().equals("metadata_url")){//metadata url - CloseableHttpClient httpClient = HttpClients.createDefault(); - HttpPost post = new HttpPost(samlDetails.getMetaUrl()); - CloseableHttpResponse response = httpClient.execute(post); - samlDetails = resolveMetaData(samlDetails,response.getEntity().getContent());; - response.close(); - httpClient.close(); - } - - if(samlDetails.getTrustCert()!=null) { - samlDetails.setCertSubject(samlDetails.getTrustCert().getSubjectDN().getName()); - samlDetails.setCertExpiration(samlDetails.getTrustCert().getNotAfter().toString()); - - samlDetails.setCertIssuer(X509CertUtils.getCommonName(samlDetails.getTrustCert().getIssuerX500Principal())); - - KeyStore keyStore = KeyStoreUtil.clone(idpKeyStoreLoader.getKeyStore(),idpKeyStoreLoader.getKeystorePassword()); - - KeyStore trustKeyStore = null; - if (!samlDetails.getEntityId().equals("")) { - trustKeyStore = KeyStoreUtil.importTrustCertificate(keyStore,samlDetails.getTrustCert(), samlDetails.getEntityId()); - } else { - trustKeyStore = KeyStoreUtil.importTrustCertificate(keyStore,samlDetails.getTrustCert()); - } - - byte[] keyStoreByte = KeyStoreUtil.keyStore2Bytes(trustKeyStore,idpKeyStoreLoader.getKeystorePassword()); - - // store KeyStore content - samlDetails.setKeyStore(keyStoreByte); } - return samlDetails; }