diff --git a/maxkey-authentications/maxkey-authentication-otp/src/main/java/org/maxkey/password/onetimepwd/OtpAuthnService.java b/maxkey-authentications/maxkey-authentication-otp/src/main/java/org/maxkey/password/onetimepwd/OtpAuthnService.java index 75c4b03a..5e694d78 100644 --- a/maxkey-authentications/maxkey-authentication-otp/src/main/java/org/maxkey/password/onetimepwd/OtpAuthnService.java +++ b/maxkey-authentications/maxkey-authentication-otp/src/main/java/org/maxkey/password/onetimepwd/OtpAuthnService.java @@ -1,3 +1,20 @@ +/* + * Copyright [2022] [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.password.onetimepwd; import java.sql.Types; diff --git a/maxkey-authentications/maxkey-authentication-social/src/main/java/me/zhyd/oauth/request/AuthHuaweiWeLinkRequest.java b/maxkey-authentications/maxkey-authentication-social/src/main/java/me/zhyd/oauth/request/AuthHuaweiWeLinkRequest.java index 42f32b56..75e6ca76 100644 --- a/maxkey-authentications/maxkey-authentication-social/src/main/java/me/zhyd/oauth/request/AuthHuaweiWeLinkRequest.java +++ b/maxkey-authentications/maxkey-authentication-social/src/main/java/me/zhyd/oauth/request/AuthHuaweiWeLinkRequest.java @@ -1,3 +1,20 @@ +/* + * Copyright [2022] [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 me.zhyd.oauth.request; import com.alibaba.fastjson.JSONObject; import me.zhyd.oauth.cache.AuthStateCache; diff --git a/maxkey-authentications/maxkey-authentication-social/src/main/java/me/zhyd/oauth/request/WeLinkAuthDefaultSource.java b/maxkey-authentications/maxkey-authentication-social/src/main/java/me/zhyd/oauth/request/WeLinkAuthDefaultSource.java index 5a7cf8a5..5e3f7c70 100644 --- a/maxkey-authentications/maxkey-authentication-social/src/main/java/me/zhyd/oauth/request/WeLinkAuthDefaultSource.java +++ b/maxkey-authentications/maxkey-authentication-social/src/main/java/me/zhyd/oauth/request/WeLinkAuthDefaultSource.java @@ -1,3 +1,20 @@ +/* + * Copyright [2022] [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 me.zhyd.oauth.request; import me.zhyd.oauth.config.AuthSource; diff --git a/maxkey-common/src/main/java/org/maxkey/crypto/jose/keystore/JWKSetKeyStore.java b/maxkey-common/src/main/java/org/maxkey/crypto/jose/keystore/JWKSetKeyStore.java index 27f0f053..3f09f33c 100644 --- a/maxkey-common/src/main/java/org/maxkey/crypto/jose/keystore/JWKSetKeyStore.java +++ b/maxkey-common/src/main/java/org/maxkey/crypto/jose/keystore/JWKSetKeyStore.java @@ -47,6 +47,16 @@ public class JWKSetKeyStore { this.jwkSet = jwkSet; initializeJwkSet(); } + + public JWKSetKeyStore(String jwkSetJsonString) { + try { + this.jwkSet = JWKSet.parse(jwkSetJsonString); + } catch (ParseException e) { + _logger.error("ParseException", e); + } + initializeJwkSet(); + } + private void initializeJwkSet() { diff --git a/maxkey-common/src/main/java/org/maxkey/crypto/jwt/encryption/service/impl/DefaultJwtEncryptionAndDecryptionService.java b/maxkey-common/src/main/java/org/maxkey/crypto/jwt/encryption/service/impl/DefaultJwtEncryptionAndDecryptionService.java index 0f707b96..f47236fe 100644 --- a/maxkey-common/src/main/java/org/maxkey/crypto/jwt/encryption/service/impl/DefaultJwtEncryptionAndDecryptionService.java +++ b/maxkey-common/src/main/java/org/maxkey/crypto/jwt/encryption/service/impl/DefaultJwtEncryptionAndDecryptionService.java @@ -159,6 +159,10 @@ public class DefaultJwtEncryptionAndDecryptionService implements JwtEncryptionAn return defaultAlgorithm; } + public void setDefaultAlgorithm(String algorithm) { + defaultAlgorithm = JWEAlgorithm.parse(algorithm); + } + public void setDefaultAlgorithm(JWEAlgorithm defaultAlgorithm) { this.defaultAlgorithm = defaultAlgorithm; } @@ -297,5 +301,23 @@ public class DefaultJwtEncryptionAndDecryptionService implements JwtEncryptionAn return encs; } - + public EncryptionMethod parseEncryptionMethod(String encryptionMethodName) { + EncryptionMethod encryptionMethod = null; + if(encryptionMethodName.equalsIgnoreCase("A128GCM")) { + encryptionMethod = EncryptionMethod.A128GCM; + }else if(encryptionMethodName.equalsIgnoreCase("A192GCM")) { + encryptionMethod = EncryptionMethod.A192GCM; + }else if(encryptionMethodName.equalsIgnoreCase("A256GCM")) { + encryptionMethod = EncryptionMethod.A256GCM; + }else if(encryptionMethodName.equalsIgnoreCase("A128CBC_HS256")) { + encryptionMethod = EncryptionMethod.A128CBC_HS256; + }else if(encryptionMethodName.equalsIgnoreCase("A192CBC_HS384")) { + encryptionMethod = EncryptionMethod.A192CBC_HS384; + }else if(encryptionMethodName.equalsIgnoreCase("A256CBC_HS512")) { + encryptionMethod = EncryptionMethod.A256CBC_HS512; + }else if(encryptionMethodName.equalsIgnoreCase("XC20P")) { + encryptionMethod = EncryptionMethod.XC20P; + } + return encryptionMethod; + } } diff --git a/maxkey-common/src/test/java/org/maxkey/crypto/signature/RSAKeyTest.java b/maxkey-common/src/test/java/org/maxkey/crypto/signature/RSAKeyTest.java new file mode 100644 index 00000000..9d8c8afc --- /dev/null +++ b/maxkey-common/src/test/java/org/maxkey/crypto/signature/RSAKeyTest.java @@ -0,0 +1,78 @@ +/* + * Copyright [2022] [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.crypto.signature; + +import java.security.SecureRandom; + +import org.maxkey.crypto.Base64Utils; + +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.JWSAlgorithm; +import com.nimbusds.jose.JWSHeader; +import com.nimbusds.jose.JWSObject; +import com.nimbusds.jose.JWSSigner; +import com.nimbusds.jose.Payload; +import com.nimbusds.jose.crypto.MACSigner; +import com.nimbusds.jose.jwk.KeyUse; +import com.nimbusds.jose.jwk.OctetSequenceKey; +import com.nimbusds.jose.jwk.RSAKey; +import com.nimbusds.jose.jwk.gen.OctetSequenceKeyGenerator; +import com.nimbusds.jose.jwk.gen.RSAKeyGenerator; + +public class RSAKeyTest { + + public static void main(String[] args) throws JOSEException { + // RSA signatures require a public and private RSA key pair, the public key + // must be made known to the JWS recipient in order to verify the signatures + RSAKey rsaJWK = new RSAKeyGenerator(2048) + .keyID("123") + .keyUse(KeyUse.SIGNATURE) + .algorithm(JWSAlgorithm.RS256) + .generate(); + RSAKey rsaPublicJWK = rsaJWK.toPublicJWK(); + System.out.println(rsaPublicJWK.toJSONString()); + + System.out.println(rsaJWK.toJSONString()); + + byte[] sharedKey = new byte[32]; + new SecureRandom().nextBytes(sharedKey); + System.out.println(Base64Utils.encoder(sharedKey)); + + + OctetSequenceKey octKey= new OctetSequenceKeyGenerator(2048) + .keyID("123") + .keyUse(KeyUse.SIGNATURE) + .algorithm(JWSAlgorithm.HS256) + .generate(); + System.out.println(octKey.toJSONString()); + + // Create HMAC signer + JWSSigner signer = new MACSigner(octKey); + + // Prepare JWS object with "Hello, world!" payload + JWSObject jwsObject = new JWSObject(new JWSHeader(JWSAlgorithm.HS256), new Payload("Hello, world!")); + + // Apply the HMAC + jwsObject.sign(signer); + String s = jwsObject.serialize(); + System.out.println(s); + + System.out.print("A128KW".substring(1, 4)); + } + +} diff --git a/maxkey-core/src/main/java/org/maxkey/entity/Accounts.java b/maxkey-core/src/main/java/org/maxkey/entity/Accounts.java index b188e92e..87031391 100644 --- a/maxkey-core/src/main/java/org/maxkey/entity/Accounts.java +++ b/maxkey-core/src/main/java/org/maxkey/entity/Accounts.java @@ -87,13 +87,13 @@ public class Accounts extends JpaBaseEntity implements Serializable { this.id = id; } - public Accounts(String uid, String appId) { - this.userId = uid; + public Accounts(String userId, String appId) { + this.userId = userId; this.appId = appId; } - public Accounts(String uid, String appId, String password) { - this.userId = uid; + public Accounts(String userId, String appId, String password) { + this.userId = userId; this.appId = appId; this.relatedPassword = password; } @@ -102,8 +102,8 @@ public class Accounts extends JpaBaseEntity implements Serializable { return userId; } - public void setUserId(String uid) { - this.userId = uid; + public void setUserId(String userId) { + this.userId = userId; } public String getUsername() { diff --git a/maxkey-core/src/main/java/org/maxkey/entity/EmailSenders.java b/maxkey-core/src/main/java/org/maxkey/entity/EmailSenders.java index ca1420ec..56f61274 100644 --- a/maxkey-core/src/main/java/org/maxkey/entity/EmailSenders.java +++ b/maxkey-core/src/main/java/org/maxkey/entity/EmailSenders.java @@ -1,3 +1,20 @@ +/* + * Copyright [2022] [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.entity; import javax.persistence.Column; diff --git a/maxkey-core/src/main/java/org/maxkey/entity/apps/Apps.java b/maxkey-core/src/main/java/org/maxkey/entity/apps/Apps.java index e1b179c5..38da6942 100644 --- a/maxkey-core/src/main/java/org/maxkey/entity/apps/Apps.java +++ b/maxkey-core/src/main/java/org/maxkey/entity/apps/Apps.java @@ -28,7 +28,6 @@ import javax.persistence.Table; import org.apache.mybatis.jpa.persistence.JpaBaseEntity; import org.maxkey.constants.ConstsBoolean; -import org.maxkey.entity.Accounts; import org.springframework.web.multipart.MultipartFile; @Entity @@ -141,7 +140,6 @@ public class Apps extends JpaBaseEntity implements Serializable { @Column private String adapter; - protected Accounts appUser; @Column protected int sortIndex; @@ -464,14 +462,6 @@ public class Apps extends JpaBaseEntity implements Serializable { this.adapter = adapter; } - public Accounts getAppUser() { - return appUser; - } - - public void setAppUser(Accounts appUser) { - this.appUser = appUser; - } - public String getPrincipal() { return principal; } @@ -659,8 +649,6 @@ public class Apps extends JpaBaseEntity implements Serializable { builder.append(adapterName); builder.append(", adapter="); builder.append(adapter); - builder.append(", appUser="); - builder.append(appUser); builder.append(", sortIndex="); builder.append(sortIndex); builder.append(", status="); diff --git a/maxkey-core/src/main/java/org/maxkey/entity/apps/AppsCasDetails.java b/maxkey-core/src/main/java/org/maxkey/entity/apps/AppsCasDetails.java index 03c9a410..ad5bc84f 100644 --- a/maxkey-core/src/main/java/org/maxkey/entity/apps/AppsCasDetails.java +++ b/maxkey-core/src/main/java/org/maxkey/entity/apps/AppsCasDetails.java @@ -44,6 +44,8 @@ public class AppsCasDetails extends Apps { private String callbackUrl; @Column private String instId; + @Column + private String casUser; private String instName; @@ -79,6 +81,14 @@ public class AppsCasDetails extends Apps { this.expires = expires; } + public String getCasUser() { + return casUser; + } + + public void setCasUser(String casUser) { + this.casUser = casUser; + } + public String getInstId() { return instId; } diff --git a/maxkey-core/src/main/java/org/maxkey/entity/apps/AppsJwtDetails.java b/maxkey-core/src/main/java/org/maxkey/entity/apps/AppsJwtDetails.java index ed94daa1..fca65ef7 100644 --- a/maxkey-core/src/main/java/org/maxkey/entity/apps/AppsJwtDetails.java +++ b/maxkey-core/src/main/java/org/maxkey/entity/apps/AppsJwtDetails.java @@ -44,6 +44,15 @@ public class AppsJwtDetails extends Apps { @Column @GeneratedValue(strategy=GenerationType.AUTO,generator="snowflakeid") protected String id; + + @Column + private String subject; + + @Column + private String issuer; + + @Column + private String audience; /** * */ @@ -53,12 +62,18 @@ public class AppsJwtDetails extends Apps { @Column private String tokenType; @Column - private String cookieName; + private String jwtName; @Column private String algorithm; @Column private String algorithmKey; @Column + private String encryptionMethod; + @Column + private String signature; + @Column + private String signatureKey; + @Column private String expires; @Column private String instId; @@ -80,7 +95,37 @@ public class AppsJwtDetails extends Apps { } - public String getRedirectUri() { + public String getSubject() { + return subject; + } + + + public void setSubject(String subject) { + this.subject = subject; + } + + + public String getIssuer() { + return issuer; + } + + + public void setIssuer(String issuer) { + this.issuer = issuer; + } + + + public String getAudience() { + return audience; + } + + + public void setAudience(String audience) { + this.audience = audience; + } + + + public String getRedirectUri() { return redirectUri; } @@ -100,17 +145,19 @@ public class AppsJwtDetails extends Apps { } - public String getCookieName() { - return cookieName; - } - public void setCookieName(String cookieName) { - this.cookieName = cookieName; - } + public String getJwtName() { + return jwtName; + } - public String getAlgorithm() { + public void setJwtName(String jwtName) { + this.jwtName = jwtName; + } + + + public String getAlgorithm() { return algorithm; } @@ -130,7 +177,37 @@ public class AppsJwtDetails extends Apps { } - public String getExpires() { + public String getEncryptionMethod() { + return encryptionMethod; + } + + + public void setEncryptionMethod(String encryptionMethod) { + this.encryptionMethod = encryptionMethod; + } + + + public String getSignature() { + return signature; + } + + + public void setSignature(String signature) { + this.signature = signature; + } + + + public String getSignatureKey() { + return signatureKey; + } + + + public void setSignatureKey(String signatureKey) { + this.signatureKey = signatureKey; + } + + + public String getExpires() { return expires; } @@ -169,8 +246,8 @@ public class AppsJwtDetails extends Apps { builder.append(redirectUri); builder.append(", tokenType="); builder.append(tokenType); - builder.append(", cookieName="); - builder.append(cookieName); + builder.append(", jwtName="); + builder.append(jwtName); builder.append(", algorithm="); builder.append(algorithm); builder.append(", algorithmKey="); 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 55dff768..5c987bc9 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 @@ -53,15 +53,24 @@ public class AppsOAuth20Details extends Apps { private String approvalPrompt; // for OpenID Connect - private String idTokenSigningAlgorithm; - private String idTokenEncryptedAlgorithm; - private String idTokenEncryptionMethod; - private String userInfoSigningAlgorithm; - private String userInfoEncryptedAlgorithm; - private String userInfoEncryptionMethod; - - private String jwksUri; + private String issuer; + + private String audience; + + private String algorithm; + + private String algorithmKey; + + private String encryptionMethod; + + private String signature; + + private String signatureKey; + + private String subject; + + private String userInfoResponse; private String pkce; @@ -109,19 +118,22 @@ public class AppsOAuth20Details extends Apps { this.refreshTokenValiditySeconds = baseClientDetails.getRefreshTokenValiditySeconds(); this.approvalPrompt = baseClientDetails.isAutoApprove("all") + ""; - this.idTokenEncryptedAlgorithm = baseClientDetails.getIdTokenEncryptedAlgorithm(); - this.idTokenEncryptionMethod = baseClientDetails.getIdTokenEncryptionMethod(); - this.idTokenSigningAlgorithm = baseClientDetails.getIdTokenSigningAlgorithm(); - - this.userInfoEncryptedAlgorithm = baseClientDetails.getUserInfoEncryptedAlgorithm(); - this.userInfoEncryptionMethod = baseClientDetails.getUserInfoEncryptionMethod(); - this.userInfoSigningAlgorithm = baseClientDetails.getUserInfoSigningAlgorithm(); - - this.jwksUri = baseClientDetails.getJwksUri(); + this.audience = baseClientDetails.getAudience(); + this.issuer = baseClientDetails.getIssuer(); + + this.algorithm = baseClientDetails.getAlgorithm(); + this.algorithmKey = baseClientDetails.getAlgorithmKey(); + this.encryptionMethod = baseClientDetails.getEncryptionMethod(); + + this.signature = baseClientDetails.getSignature(); + this.signatureKey = baseClientDetails.getSignatureKey(); + this.approvalPrompt = baseClientDetails.getApprovalPrompt(); this.pkce = baseClientDetails.getPkce(); this.instId = baseClientDetails.getInstId(); + this.subject = baseClientDetails.getSubject(); + this.userInfoResponse = baseClientDetails.getUserInfoResponse(); } @@ -155,7 +167,23 @@ public class AppsOAuth20Details extends Apps { this.approvalPrompt = approvalPrompt; } - /** + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject; + } + + public String getUserInfoResponse() { + return userInfoResponse; + } + + public void setUserInfoResponse(String userInfoResponse) { + this.userInfoResponse = userInfoResponse; + } + + /** * @param clientId the clientId to set */ public void setClientId(String clientId) { @@ -274,61 +302,64 @@ public class AppsOAuth20Details extends Apps { this.refreshTokenValiditySeconds = refreshTokenValiditySeconds; } - public String getIdTokenSigningAlgorithm() { - return idTokenSigningAlgorithm; - } + + public String getIssuer() { + return issuer; + } - public void setIdTokenSigningAlgorithm(String idTokenSigningAlgorithm) { - this.idTokenSigningAlgorithm = idTokenSigningAlgorithm; - } + public void setIssuer(String issuer) { + this.issuer = issuer; + } - public String getIdTokenEncryptedAlgorithm() { - return idTokenEncryptedAlgorithm; - } + public String getAudience() { + return audience; + } - public void setIdTokenEncryptedAlgorithm(String idTokenEncryptedAlgorithm) { - this.idTokenEncryptedAlgorithm = idTokenEncryptedAlgorithm; - } + public void setAudience(String audience) { + this.audience = audience; + } - public String getIdTokenEncryptionMethod() { - return idTokenEncryptionMethod; - } + public String getAlgorithm() { + return algorithm; + } - public void setIdTokenEncryptionMethod(String idTokenEncryptionMethod) { - this.idTokenEncryptionMethod = idTokenEncryptionMethod; - } + public void setAlgorithm(String algorithm) { + this.algorithm = algorithm; + } - public String getUserInfoSigningAlgorithm() { - return userInfoSigningAlgorithm; - } + public String getAlgorithmKey() { + return algorithmKey; + } - public void setUserInfoSigningAlgorithm(String userInfoSigningAlgorithm) { - this.userInfoSigningAlgorithm = userInfoSigningAlgorithm; - } + public void setAlgorithmKey(String algorithmKey) { + this.algorithmKey = algorithmKey; + } - public String getUserInfoEncryptedAlgorithm() { - return userInfoEncryptedAlgorithm; - } + public String getEncryptionMethod() { + return encryptionMethod; + } - public void setUserInfoEncryptedAlgorithm(String userInfoEncryptedAlgorithm) { - this.userInfoEncryptedAlgorithm = userInfoEncryptedAlgorithm; - } + public void setEncryptionMethod(String encryptionMethod) { + this.encryptionMethod = encryptionMethod; + } - public String getUserInfoEncryptionMethod() { - return userInfoEncryptionMethod; - } + public String getSignature() { + return signature; + } - public void setUserInfoEncryptionMethod(String userInfoEncryptionMethod) { - this.userInfoEncryptionMethod = userInfoEncryptionMethod; - } + public void setSignature(String signature) { + this.signature = signature; + } + + public String getSignatureKey() { + return signatureKey; + } + + public void setSignatureKey(String signatureKey) { + this.signatureKey = signatureKey; + } - public String getJwksUri() { - return jwksUri; - } - public void setJwksUri(String jwksUri) { - this.jwksUri = jwksUri; - } public String getInstId() { return instId; @@ -354,15 +385,19 @@ public class AppsOAuth20Details extends Apps { baseClientDetails.setClientSecret(this.getClientSecret()); baseClientDetails.setAutoApproveScopes(baseClientDetails.getScope()); - baseClientDetails.setIdTokenEncryptedAlgorithm(this.getIdTokenEncryptedAlgorithm()); - baseClientDetails.setIdTokenEncryptionMethod(this.getIdTokenEncryptionMethod()); - baseClientDetails.setIdTokenSigningAlgorithm(this.getIdTokenSigningAlgorithm()); - - baseClientDetails.setUserInfoEncryptedAlgorithm(this.getUserInfoEncryptedAlgorithm()); - baseClientDetails.setUserInfoEncryptionMethod(this.getUserInfoEncryptionMethod()); - baseClientDetails.setUserInfoSigningAlgorithm(this.getUserInfoSigningAlgorithm()); - - baseClientDetails.setJwksUri(this.getJwksUri()); + baseClientDetails.setAudience(this.getAudience()); + baseClientDetails.setIssuer(this.getIssuer()); + + baseClientDetails.setAlgorithm(this.getAlgorithm()); + baseClientDetails.setAlgorithmKey(this.getAlgorithmKey()); + baseClientDetails.setEncryptionMethod(this.getEncryptionMethod()); + + baseClientDetails.setSignature(this.getSignature()); + baseClientDetails.setSignatureKey(this.getSignatureKey()); + + baseClientDetails.setSubject(this.getSubject()); + baseClientDetails.setUserInfoResponse(this.userInfoResponse); + baseClientDetails.setApprovalPrompt(this.getApprovalPrompt()); baseClientDetails.setPkce(this.getPkce()); baseClientDetails.setProtocol(this.getProtocol()); @@ -371,44 +406,50 @@ public class AppsOAuth20Details extends Apps { } @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("AppsOAuth20Details [clientId="); - builder.append(clientId); - builder.append(", clientSecret="); - builder.append(clientSecret); - builder.append(", scope="); - builder.append(scope); - builder.append(", resourceIds="); - builder.append(resourceIds); - builder.append(", authorizedGrantTypes="); - builder.append(authorizedGrantTypes); - builder.append(", registeredRedirectUris="); - builder.append(registeredRedirectUris); - builder.append(", authorities="); - builder.append(authorities); - builder.append(", accessTokenValiditySeconds="); - builder.append(accessTokenValiditySeconds); - builder.append(", refreshTokenValiditySeconds="); - builder.append(refreshTokenValiditySeconds); - builder.append(", approvalPrompt="); - builder.append(approvalPrompt); - builder.append(", idTokenSigningAlgorithm="); - builder.append(idTokenSigningAlgorithm); - builder.append(", idTokenEncryptedAlgorithm="); - builder.append(idTokenEncryptedAlgorithm); - builder.append(", idTokenEncryptionMethod="); - builder.append(idTokenEncryptionMethod); - builder.append(", userInfoSigningAlgorithm="); - builder.append(userInfoSigningAlgorithm); - builder.append(", userInfoEncryptedAlgorithm="); - builder.append(userInfoEncryptedAlgorithm); - builder.append(", userInfoEncryptionMethod="); - builder.append(userInfoEncryptionMethod); - builder.append(", jwksUri="); - builder.append(jwksUri); - builder.append("]"); - return builder.toString(); - } + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("AppsOAuth20Details [clientId="); + builder.append(clientId); + builder.append(", clientSecret="); + builder.append(clientSecret); + builder.append(", scope="); + builder.append(scope); + builder.append(", resourceIds="); + builder.append(resourceIds); + builder.append(", authorizedGrantTypes="); + builder.append(authorizedGrantTypes); + builder.append(", registeredRedirectUris="); + builder.append(registeredRedirectUris); + builder.append(", authorities="); + builder.append(authorities); + builder.append(", accessTokenValiditySeconds="); + builder.append(accessTokenValiditySeconds); + builder.append(", refreshTokenValiditySeconds="); + builder.append(refreshTokenValiditySeconds); + builder.append(", approvalPrompt="); + builder.append(approvalPrompt); + builder.append(", issuer="); + builder.append(issuer); + builder.append(", audience="); + builder.append(audience); + builder.append(", algorithm="); + builder.append(algorithm); + builder.append(", algorithmKey="); + builder.append(algorithmKey); + builder.append(", encryptionMethod="); + builder.append(encryptionMethod); + builder.append(", signature="); + builder.append(signature); + builder.append(", signatureKey="); + builder.append(signatureKey); + builder.append(", pkce="); + builder.append(pkce); + builder.append(", instId="); + builder.append(instId); + builder.append(", instName="); + builder.append(instName); + builder.append("]"); + return builder.toString(); + } } diff --git a/maxkey-core/src/main/java/org/maxkey/entity/apps/oauth2/provider/ClientDetails.java b/maxkey-core/src/main/java/org/maxkey/entity/apps/oauth2/provider/ClientDetails.java index e79bfbce..30f199df 100644 --- a/maxkey-core/src/main/java/org/maxkey/entity/apps/oauth2/provider/ClientDetails.java +++ b/maxkey-core/src/main/java/org/maxkey/entity/apps/oauth2/provider/ClientDetails.java @@ -132,22 +132,26 @@ public interface ClientDetails extends Serializable { /* * for OpenID Connect */ - public String getIdTokenEncryptedAlgorithm() ; + public String getIssuer() ; - public String getIdTokenSigningAlgorithm() ; + public String getAudience() ; - public String getIdTokenEncryptionMethod(); + public String getAlgorithm(); - public String getUserInfoSigningAlgorithm(); + public String getAlgorithmKey(); - public String getUserInfoEncryptedAlgorithm(); + public String getEncryptionMethod(); - public String getUserInfoEncryptionMethod(); + public String getSignature(); - public String getJwksUri(); + public String getSignatureKey(); public String getApprovalPrompt(); + public String getSubject(); + + public String getUserInfoResponse(); + public String getPkce(); public String getProtocol(); diff --git a/maxkey-core/src/main/java/org/maxkey/entity/apps/oauth2/provider/client/BaseClientDetails.java b/maxkey-core/src/main/java/org/maxkey/entity/apps/oauth2/provider/client/BaseClientDetails.java index fe7b2de4..176bb785 100644 --- a/maxkey-core/src/main/java/org/maxkey/entity/apps/oauth2/provider/client/BaseClientDetails.java +++ b/maxkey-core/src/main/java/org/maxkey/entity/apps/oauth2/provider/client/BaseClientDetails.java @@ -82,15 +82,24 @@ public class BaseClientDetails implements ClientDetails { private Map additionalInformation = new LinkedHashMap(); //for OpenID Connect - private String idTokenSigningAlgorithm; - private String idTokenEncryptedAlgorithm; - private String idTokenEncryptionMethod; - private String userInfoSigningAlgorithm; - private String userInfoEncryptedAlgorithm; - private String userInfoEncryptionMethod; + private String issuer; - private String jwksUri; + private String audience; + + private String algorithm; + + private String algorithmKey; + + private String encryptionMethod; + + private String signature; + + private String signatureKey; + + private String subject; + + private String userInfoResponse; private String approvalPrompt; @@ -310,65 +319,79 @@ public class BaseClientDetails implements ClientDetails { this.additionalInformation.put(key, value); } - - - public String getIdTokenEncryptedAlgorithm() { - return idTokenEncryptedAlgorithm; + public String getIssuer() { + return issuer; } - public void setIdTokenEncryptedAlgorithm(String idTokenEncryptedAlgorithm) { - this.idTokenEncryptedAlgorithm = idTokenEncryptedAlgorithm; + public void setIssuer(String issuer) { + this.issuer = issuer; } - public String getIdTokenSigningAlgorithm() { - return idTokenSigningAlgorithm; + public String getAudience() { + return audience; } - public void setIdTokenSigningAlgorithm(String idTokenSigningAlgorithm) { - this.idTokenSigningAlgorithm = idTokenSigningAlgorithm; + public void setAudience(String audience) { + this.audience = audience; } - public String getIdTokenEncryptionMethod() { - return idTokenEncryptionMethod; + public String getAlgorithm() { + return algorithm; } - public void setIdTokenEncryptionMethod(String idTokenEncryptionMethod) { - this.idTokenEncryptionMethod = idTokenEncryptionMethod; + public void setAlgorithm(String algorithm) { + this.algorithm = algorithm; } - public String getUserInfoSigningAlgorithm() { - return userInfoSigningAlgorithm; + public String getAlgorithmKey() { + return algorithmKey; } - public void setUserInfoSigningAlgorithm(String userInfoSigningAlgorithm) { - this.userInfoSigningAlgorithm = userInfoSigningAlgorithm; + public void setAlgorithmKey(String algorithmKey) { + this.algorithmKey = algorithmKey; } - public String getUserInfoEncryptedAlgorithm() { - return userInfoEncryptedAlgorithm; + public String getEncryptionMethod() { + return encryptionMethod; } - public void setUserInfoEncryptedAlgorithm(String userInfoEncryptedAlgorithm) { - this.userInfoEncryptedAlgorithm = userInfoEncryptedAlgorithm; + public void setEncryptionMethod(String encryptionMethod) { + this.encryptionMethod = encryptionMethod; } - public String getUserInfoEncryptionMethod() { - return userInfoEncryptionMethod; + public String getSignature() { + return signature; } - public void setUserInfoEncryptionMethod(String userInfoEncryptionMethod) { - this.userInfoEncryptionMethod = userInfoEncryptionMethod; + public void setSignature(String signature) { + this.signature = signature; } - public String getJwksUri() { - return jwksUri; + public String getSignatureKey() { + return signatureKey; } - public void setJwksUri(String jwksUri) { - this.jwksUri = jwksUri; + public void setSignatureKey(String signatureKey) { + this.signatureKey = signatureKey; } + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject; + } + + public String getUserInfoResponse() { + return userInfoResponse; + } + + public void setUserInfoResponse(String userInfoResponse) { + this.userInfoResponse = userInfoResponse; + } + public String getApprovalPrompt() { return approvalPrompt; } @@ -492,49 +515,55 @@ public class BaseClientDetails implements ClientDetails { } @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("BaseClientDetails [clientId="); - builder.append(clientId); - builder.append(", clientSecret="); - builder.append(clientSecret); - builder.append(", scope="); - builder.append(scope); - builder.append(", resourceIds="); - builder.append(resourceIds); - builder.append(", authorizedGrantTypes="); - builder.append(authorizedGrantTypes); - builder.append(", registeredRedirectUris="); - builder.append(registeredRedirectUris); - builder.append(", autoApproveScopes="); - builder.append(autoApproveScopes); - builder.append(", authorities="); - builder.append(authorities); - builder.append(", accessTokenValiditySeconds="); - builder.append(accessTokenValiditySeconds); - builder.append(", refreshTokenValiditySeconds="); - builder.append(refreshTokenValiditySeconds); - builder.append(", additionalInformation="); - builder.append(additionalInformation); - builder.append(", idTokenSigningAlgorithm="); - builder.append(idTokenSigningAlgorithm); - builder.append(", idTokenEncryptedAlgorithm="); - builder.append(idTokenEncryptedAlgorithm); - builder.append(", idTokenEncryptionMethod="); - builder.append(idTokenEncryptionMethod); - builder.append(", userInfoSigningAlgorithm="); - builder.append(userInfoSigningAlgorithm); - builder.append(", userInfoEncryptedAlgorithm="); - builder.append(userInfoEncryptedAlgorithm); - builder.append(", userInfoEncryptionMethod="); - builder.append(userInfoEncryptionMethod); - builder.append(", jwksUri="); - builder.append(jwksUri); - builder.append(", approvalPrompt="); - builder.append(approvalPrompt); - builder.append("]"); - return builder.toString(); - } + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("BaseClientDetails [clientId="); + builder.append(clientId); + builder.append(", clientSecret="); + builder.append(clientSecret); + builder.append(", scope="); + builder.append(scope); + builder.append(", resourceIds="); + builder.append(resourceIds); + builder.append(", authorizedGrantTypes="); + builder.append(authorizedGrantTypes); + builder.append(", registeredRedirectUris="); + builder.append(registeredRedirectUris); + builder.append(", autoApproveScopes="); + builder.append(autoApproveScopes); + builder.append(", authorities="); + builder.append(authorities); + builder.append(", accessTokenValiditySeconds="); + builder.append(accessTokenValiditySeconds); + builder.append(", refreshTokenValiditySeconds="); + builder.append(refreshTokenValiditySeconds); + builder.append(", additionalInformation="); + builder.append(additionalInformation); + builder.append(", issuer="); + builder.append(issuer); + builder.append(", audience="); + builder.append(audience); + builder.append(", algorithm="); + builder.append(algorithm); + builder.append(", algorithmKey="); + builder.append(algorithmKey); + builder.append(", encryptionMethod="); + builder.append(encryptionMethod); + builder.append(", signature="); + builder.append(signature); + builder.append(", signatureKey="); + builder.append(signatureKey); + builder.append(", approvalPrompt="); + builder.append(approvalPrompt); + builder.append(", pkce="); + builder.append(pkce); + builder.append(", protocol="); + builder.append(protocol); + builder.append(", instId="); + builder.append(instId); + builder.append("]"); + return builder.toString(); + } diff --git a/maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/endpoint/AuthorizeBaseEndpoint.java b/maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/endpoint/AuthorizeBaseEndpoint.java index d2e8f1ad..361ef9db 100644 --- a/maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/endpoint/AuthorizeBaseEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/endpoint/AuthorizeBaseEndpoint.java @@ -21,6 +21,7 @@ package org.maxkey.authz.endpoint; import org.apache.commons.lang3.StringUtils; +import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; import org.maxkey.configuration.ApplicationConfig; import org.maxkey.crypto.password.PasswordReciprocal; import org.maxkey.entity.Accounts; @@ -73,34 +74,30 @@ public class AuthorizeBaseEndpoint { } protected Accounts getAccounts(Apps app){ - Accounts account=new Accounts(); - UserInfo userInfo=WebContext.getUserInfo(); + UserInfo userInfo = WebContext.getUserInfo(); Apps loadApp = getApp(app.getId()); + + Accounts account = new Accounts(userInfo.getId(),loadApp.getId()); + account.setUsername(userInfo.getUsername()); + account.setAppName(app.getName()); + if(loadApp.getCredential() == Apps.CREDENTIALS.USER_DEFINED){ account = accountsService.load(new Accounts(userInfo.getId(),loadApp.getId())); if(account != null){ - account.setRelatedPassword(PasswordReciprocal.getInstance().decoder(account.getRelatedPassword())); + account.setRelatedPassword( + PasswordReciprocal.getInstance().decoder(account.getRelatedPassword())); } }else if(loadApp.getCredential() == Apps.CREDENTIALS.SHARED){ account.setRelatedUsername(loadApp.getSharedUsername()); account.setRelatedPassword(PasswordReciprocal.getInstance().decoder(loadApp.getSharedPassword())); - }else if(loadApp.getCredential() == Apps.CREDENTIALS.SYSTEM){ - if(loadApp.getSystemUserAttr().equalsIgnoreCase("userId")){ - account.setUsername(userInfo.getId()); - }else if(loadApp.getSystemUserAttr().equalsIgnoreCase("username")){ - account.setUsername(userInfo.getUsername()); - }else if(loadApp.getSystemUserAttr().equalsIgnoreCase("employeeNumber")){ - account.setUsername(userInfo.getEmployeeNumber()); - }else if(loadApp.getSystemUserAttr().equalsIgnoreCase("email")){ - account.setUsername(userInfo.getEmail()); - }else if(loadApp.getSystemUserAttr().equalsIgnoreCase("windowsAccount")){ - account.setUsername(userInfo.getWindowsAccount()); - } + account.setUsername( + AbstractAuthorizeAdapter.getValueByUserAttr(userInfo, loadApp.getSystemUserAttr()) + ); //decoder database stored encode password - account.setRelatedPassword(PasswordReciprocal.getInstance().decoder(WebContext.getUserInfo().getDecipherable())); - + account.setRelatedPassword( + PasswordReciprocal.getInstance().decoder(WebContext.getUserInfo().getDecipherable())); }else if(loadApp.getCredential()==Apps.CREDENTIALS.NONE){ account.setUsername(userInfo.getUsername()); account.setRelatedPassword(userInfo.getUsername()); @@ -110,8 +107,10 @@ public class AuthorizeBaseEndpoint { } public ModelAndView generateInitCredentialModelAndView(String appId,String redirect_uri){ - ModelAndView modelAndView=new ModelAndView("redirect:/authz/credential/forward?appId="+appId+"&redirect_uri="+redirect_uri); + ModelAndView modelAndView = + new ModelAndView(String.format(InitCredentialURL,appId, redirect_uri)); return modelAndView; } + public static String InitCredentialURL = "redirect:/authz/credential/forward?appId=%s&redirect_uri=%s"; } diff --git a/maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/endpoint/AuthorizeCredentialEndpoint.java b/maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/endpoint/AuthorizeCredentialEndpoint.java index 829624fe..e779480f 100644 --- a/maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/endpoint/AuthorizeCredentialEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/endpoint/AuthorizeCredentialEndpoint.java @@ -77,6 +77,8 @@ public class AuthorizeCredentialEndpoint extends AuthorizeBaseEndpoint{ appUser.setRelatedUsername(identity_username); appUser.setRelatedPassword(PasswordReciprocal.getInstance().encode(identity_password)); + appUser.setInstId(WebContext.getUserInfo().getInstId()); + if(accountsService.insert(appUser)){ } diff --git a/maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/endpoint/adapter/AbstractAuthorizeAdapter.java b/maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/endpoint/adapter/AbstractAuthorizeAdapter.java index 6ebb39c2..81f774ba 100644 --- a/maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/endpoint/adapter/AbstractAuthorizeAdapter.java +++ b/maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/endpoint/adapter/AbstractAuthorizeAdapter.java @@ -19,6 +19,7 @@ package org.maxkey.authz.endpoint.adapter; import java.io.UnsupportedEncodingException; import org.apache.commons.codec.binary.Hex; +import org.apache.commons.lang3.StringUtils; import org.maxkey.authn.SigninPrincipal; import org.maxkey.constants.ConstsBoolean; import org.maxkey.crypto.Base64Utils; @@ -26,6 +27,7 @@ import org.maxkey.crypto.ReciprocalUtils; import org.maxkey.crypto.cert.CertSigner; import org.maxkey.crypto.keystore.KeyStoreLoader; import org.maxkey.crypto.password.PasswordReciprocal; +import org.maxkey.entity.Accounts; import org.maxkey.entity.UserInfo; import org.maxkey.entity.apps.Apps; import org.maxkey.web.WebContext; @@ -36,51 +38,109 @@ import org.springframework.web.servlet.ModelAndView; public abstract class AbstractAuthorizeAdapter { final static Logger _logger = LoggerFactory.getLogger(AbstractAuthorizeAdapter.class); - public PasswordReciprocal passwordReciprocal=PasswordReciprocal.getInstance(); + protected Apps app; - public abstract ModelAndView authorize(UserInfo userInfo,Object app,String data,ModelAndView modelAndView); + protected UserInfo userInfo; - public abstract String generateInfo(SigninPrincipal authentication,UserInfo userInfo,Object app); + protected Accounts account; - public String sign(String data,Apps app){ + protected SigninPrincipal authentication; + + public abstract Object generateInfo(); + + public ModelAndView authorize(ModelAndView modelAndView) { + return modelAndView; + } + + public Object sign(Object data,String signatureKey,String signature){ if(ConstsBoolean.isTrue(app.getIsSignature())){ - KeyStoreLoader keyStoreLoader=WebContext.getBean("keyStoreLoader",KeyStoreLoader.class); + KeyStoreLoader keyStoreLoader = WebContext.getBean("keyStoreLoader",KeyStoreLoader.class); try { - byte[] signature= CertSigner.sign(data.getBytes(), keyStoreLoader.getKeyStore(), keyStoreLoader.getEntityName(), keyStoreLoader.getKeystorePassword()); + byte[] signData= CertSigner.sign(data.toString().getBytes(), keyStoreLoader.getKeyStore(), keyStoreLoader.getEntityName(), keyStoreLoader.getKeystorePassword()); _logger.debug("signed Token : "+data); - _logger.debug("signature : "+signature.toString()); + _logger.debug("signature : "+signData.toString()); - - data=Base64Utils.base64UrlEncode(data.getBytes("UTF-8"))+"."+Base64Utils.base64UrlEncode(signature); + return Base64Utils.base64UrlEncode(data.toString().getBytes("UTF-8"))+"."+Base64Utils.base64UrlEncode(signData); } catch (UnsupportedEncodingException e) { - e.printStackTrace(); + _logger.error("UnsupportedEncodingException " , e); } catch (Exception e) { - e.printStackTrace(); + _logger.error("Exception " , e); } - _logger.debug("Token : "+data); + _logger.debug("Token {}" , data); }else{ _logger.debug("data not need sign ."); + return data; } - return data; + return null; } - public String encrypt(String data,String algorithmKey,String algorithm){ + public Object encrypt(Object data,String algorithmKey,String algorithm){ - algorithmKey=passwordReciprocal.decoder(algorithmKey); + algorithmKey = PasswordReciprocal.getInstance().decoder(algorithmKey); _logger.debug("algorithm : "+algorithm); _logger.debug("algorithmKey : "+algorithmKey); //Chinese , encode data to HEX try { - data = new String(Hex.encodeHex(data.getBytes("UTF-8"))); + data = new String(Hex.encodeHex(data.toString().getBytes("UTF-8"))); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } - byte[] encodeData=ReciprocalUtils.encode(data, algorithmKey, algorithm); - String tokenString=Base64Utils.base64UrlEncode(encodeData); + byte[] encodeData = ReciprocalUtils.encode(data.toString(), algorithmKey, algorithm); + String tokenString = Base64Utils.base64UrlEncode(encodeData); _logger.trace("Reciprocal then HEX Token : "+tokenString); return tokenString; } + + public static String getValueByUserAttr(UserInfo userInfo,String userAttr) { + String value = ""; + if(StringUtils.isBlank(userAttr)) { + value = userInfo.getUsername(); + }else if(userAttr.equalsIgnoreCase("username")){ + value = userInfo.getUsername(); + }else if(userAttr.equalsIgnoreCase("userId")){ + value = userInfo.getId(); + }else if(userAttr.equalsIgnoreCase("email")){ + value = userInfo.getEmail(); + }else if(userAttr.equalsIgnoreCase("mobile")){ + value = userInfo.getMobile(); + }else if(userAttr.equalsIgnoreCase("workEmail")) { + value = userInfo.getWorkEmail(); + }else if(userAttr.equalsIgnoreCase("windowsAccount")){ + value = userInfo.getWindowsAccount(); + }else if(userAttr.equalsIgnoreCase("employeeNumber")){ + value = userInfo.getEmployeeNumber(); + }else { + value = userInfo.getId(); + } + + if(StringUtils.isBlank(value)) { + value = userInfo.getUsername(); + } + + return value; + } + + public String serialize() { + return ""; + }; + + public void setAuthentication(SigninPrincipal authentication) { + this.authentication = authentication; + } + + public void setUserInfo(UserInfo userInfo) { + this.userInfo = userInfo; + } + + public void setApp(Apps app) { + this.app = app; + } + + public void setAccount(Accounts account) { + this.account = account; + } + } diff --git a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas10AuthorizeEndpoint.java b/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas10AuthorizeEndpoint.java index df744828..d2359e57 100644 --- a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas10AuthorizeEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas10AuthorizeEndpoint.java @@ -97,14 +97,14 @@ renew [OPTIONAL] - if this parameter is set, ticket validation will only succeed +" , renew " + renew ); - Ticket storedTicket=null; + Ticket storedTicket = null; try { storedTicket = ticketServices.consumeTicket(ticket); } catch (Exception e) { _logger.error("consume Ticket error " , e); } - if(storedTicket!=null){ + if(storedTicket != null){ String principal=((SigninPrincipal)storedTicket.getAuthentication().getPrincipal()).getUsername(); _logger.debug("principal "+principal); return new Service10ResponseBuilder().success() diff --git a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas20AuthorizeEndpoint.java b/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas20AuthorizeEndpoint.java index 08f65a18..36ca11b1 100644 --- a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas20AuthorizeEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas20AuthorizeEndpoint.java @@ -20,8 +20,12 @@ */ package org.maxkey.authz.cas.endpoint; +import java.lang.reflect.InvocationTargetException; + import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.beanutils.BeanUtils; import org.maxkey.authn.SigninPrincipal; import org.maxkey.authz.cas.endpoint.response.ProxyServiceResponseBuilder; import org.maxkey.authz.cas.endpoint.response.ServiceResponseBuilder; @@ -202,9 +206,6 @@ For all error codes, it is RECOMMENDED that CAS provide a more detailed message if(storedTicket!=null){ SigninPrincipal authentication = ((SigninPrincipal)storedTicket.getAuthentication().getPrincipal()); - String principal=authentication.getUsername(); - _logger.debug("principal "+principal); - serviceResponseBuilder.success().setUser(principal); if(StringUtils.isNotBlank(pgtUrl)) { ProxyGrantingTicketIOUImpl proxyGrantingTicketIOUImpl =new ProxyGrantingTicketIOUImpl(); String proxyGrantingTicketIOU=casProxyGrantingTicketServices.createTicket(proxyGrantingTicketIOUImpl); @@ -219,9 +220,21 @@ For all error codes, it is RECOMMENDED that CAS provide a more detailed message } if(ConstsBoolean.isTrue(storedTicket.getCasDetails().getIsAdapter())){ - AbstractAuthorizeAdapter adapter =(AbstractAuthorizeAdapter)Instance.newInstance(storedTicket.getCasDetails().getAdapter()); - UserInfo userInfo = (UserInfo) userInfoService.findByUsername(principal); - adapter.generateInfo(authentication,userInfo, serviceResponseBuilder); + + Object samlAdapter = Instance.newInstance(storedTicket.getCasDetails().getAdapter()); + try { + BeanUtils.setProperty(samlAdapter, "serviceResponseBuilder", serviceResponseBuilder); + } catch (IllegalAccessException | InvocationTargetException e) { + _logger.error("setProperty error . ", e); + } + + UserInfo userInfo = (UserInfo) userInfoService.findByUsername(authentication.getUsername()); + + AbstractAuthorizeAdapter adapter =(AbstractAuthorizeAdapter)samlAdapter; + adapter.setAuthentication(authentication); + adapter.setUserInfo(userInfo); + adapter.setApp(storedTicket.getCasDetails()); + adapter.generateInfo(); } }else{ serviceResponseBuilder.failure() @@ -324,14 +337,21 @@ Response on ticket validation failure: if(storedTicket!=null){ SigninPrincipal authentication = ((SigninPrincipal)storedTicket.getAuthentication().getPrincipal()); - String principal=authentication.getUsername(); - _logger.debug("principal "+principal); - serviceResponseBuilder.success().setUser(principal); - if(ConstsBoolean.isTrue(storedTicket.getCasDetails().getIsAdapter())){ - AbstractAuthorizeAdapter adapter =(AbstractAuthorizeAdapter)Instance.newInstance(storedTicket.getCasDetails().getAdapter()); - UserInfo userInfo = (UserInfo) userInfoService.findByUsername(principal); - adapter.generateInfo(authentication,userInfo, serviceResponseBuilder); + Object samlAdapter = Instance.newInstance(storedTicket.getCasDetails().getAdapter()); + try { + BeanUtils.setProperty(samlAdapter, "serviceResponseBuilder", serviceResponseBuilder); + } catch (IllegalAccessException | InvocationTargetException e) { + _logger.error("setProperty error . ", e); + } + + UserInfo userInfo = (UserInfo) userInfoService.findByUsername(authentication.getUsername()); + + AbstractAuthorizeAdapter adapter =(AbstractAuthorizeAdapter)samlAdapter; + adapter.setAuthentication(authentication); + adapter.setUserInfo(userInfo); + adapter.setApp(storedTicket.getCasDetails()); + adapter.generateInfo(); } }else{ serviceResponseBuilder.failure() diff --git a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas30AuthorizeEndpoint.java b/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas30AuthorizeEndpoint.java index a8218f2a..7d943042 100644 --- a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas30AuthorizeEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas30AuthorizeEndpoint.java @@ -20,9 +20,12 @@ */ package org.maxkey.authz.cas.endpoint; +import java.lang.reflect.InvocationTargetException; + import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.beanutils.BeanUtils; import org.maxkey.authn.SigninPrincipal; import org.maxkey.authz.cas.endpoint.response.ProxyServiceResponseBuilder; import org.maxkey.authz.cas.endpoint.response.ServiceResponseBuilder; @@ -85,9 +88,6 @@ public class Cas30AuthorizeEndpoint extends CasBaseAuthorizeEndpoint{ if(storedTicket!=null){ SigninPrincipal authentication = ((SigninPrincipal)storedTicket.getAuthentication().getPrincipal()); - String principal=authentication.getUsername(); - _logger.debug("principal "+principal); - serviceResponseBuilder.success().setUser(principal); if(StringUtils.isNotBlank(pgtUrl)) { ProxyGrantingTicketIOUImpl proxyGrantingTicketIOUImpl =new ProxyGrantingTicketIOUImpl(); String proxyGrantingTicketIOU=casProxyGrantingTicketServices.createTicket(proxyGrantingTicketIOUImpl); @@ -102,9 +102,20 @@ public class Cas30AuthorizeEndpoint extends CasBaseAuthorizeEndpoint{ } if(ConstsBoolean.isTrue(storedTicket.getCasDetails().getIsAdapter())){ - AbstractAuthorizeAdapter adapter =(AbstractAuthorizeAdapter)Instance.newInstance(storedTicket.getCasDetails().getAdapter()); - UserInfo userInfo = (UserInfo) userInfoService.findByUsername(principal); - adapter.generateInfo(authentication,userInfo, serviceResponseBuilder); + Object samlAdapter = Instance.newInstance(storedTicket.getCasDetails().getAdapter()); + try { + BeanUtils.setProperty(samlAdapter, "serviceResponseBuilder", serviceResponseBuilder); + } catch (IllegalAccessException | InvocationTargetException e) { + _logger.error("setProperty error . ", e); + } + + UserInfo userInfo = (UserInfo) userInfoService.findByUsername(authentication.getUsername()); + + AbstractAuthorizeAdapter adapter =(AbstractAuthorizeAdapter)samlAdapter; + adapter.setAuthentication(authentication); + adapter.setUserInfo(userInfo); + adapter.setApp(storedTicket.getCasDetails()); + adapter.generateInfo(); } }else{ serviceResponseBuilder.failure() @@ -171,14 +182,21 @@ public class Cas30AuthorizeEndpoint extends CasBaseAuthorizeEndpoint{ if(storedTicket!=null){ SigninPrincipal authentication = ((SigninPrincipal)storedTicket.getAuthentication().getPrincipal()); - String principal=authentication.getUsername(); - _logger.debug("principal "+principal); - serviceResponseBuilder.success().setUser(principal); - if(ConstsBoolean.isTrue(storedTicket.getCasDetails().getIsAdapter())){ - AbstractAuthorizeAdapter adapter =(AbstractAuthorizeAdapter)Instance.newInstance(storedTicket.getCasDetails().getAdapter()); - UserInfo userInfo = (UserInfo) userInfoService.findByUsername(principal); - adapter.generateInfo(authentication,userInfo, serviceResponseBuilder); + Object samlAdapter = Instance.newInstance(storedTicket.getCasDetails().getAdapter()); + try { + BeanUtils.setProperty(samlAdapter, "serviceResponseBuilder", serviceResponseBuilder); + } catch (IllegalAccessException | InvocationTargetException e) { + _logger.error("setProperty error . ", e); + } + + UserInfo userInfo = (UserInfo) userInfoService.findByUsername(authentication.getUsername()); + + AbstractAuthorizeAdapter adapter =(AbstractAuthorizeAdapter)samlAdapter; + adapter.setAuthentication(authentication); + adapter.setUserInfo(userInfo); + adapter.setApp(storedTicket.getCasDetails()); + adapter.generateInfo(); } }else{ serviceResponseBuilder.failure() diff --git a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/CasAuthorizeEndpoint.java b/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/CasAuthorizeEndpoint.java index 3caab20e..ac20bb2d 100644 --- a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/CasAuthorizeEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/CasAuthorizeEndpoint.java @@ -90,7 +90,7 @@ public class CasAuthorizeEndpoint extends CasBaseAuthorizeEndpoint{ _logger.debug(""+casDetails); Map parameterMap = WebContext.getRequestParameterMap(request); String service = casService; - _logger.debug("CAS Parameter service = " + service); + _logger.debug("CAS Parameter service = {}" , service); if(casService.indexOf("?") >-1 ) { service = casService.substring(casService.indexOf("?") + 1); if(service.indexOf("=") > -1) { @@ -99,7 +99,7 @@ public class CasAuthorizeEndpoint extends CasBaseAuthorizeEndpoint{ parameterMap.put(parameterValues[0], parameterValues[1]); } } - _logger.debug("CAS service with Parameter : " + service); + _logger.debug("CAS service with Parameter : {}" , parameterMap); } WebContext.setAttribute( CasConstants.PARAMETER.PARAMETER_MAP, @@ -117,10 +117,10 @@ public class CasAuthorizeEndpoint extends CasBaseAuthorizeEndpoint{ @AuthenticationPrincipal Object user, HttpServletRequest request, HttpServletResponse response){ - AppsCasDetails casDetails=(AppsCasDetails)WebContext.getAttribute(CasConstants.PARAMETER.ENDPOINT_CAS_DETAILS); - ServiceTicketImpl serviceTicket=new ServiceTicketImpl(WebContext.getAuthentication(),casDetails); + AppsCasDetails casDetails = (AppsCasDetails)WebContext.getAttribute(CasConstants.PARAMETER.ENDPOINT_CAS_DETAILS); + ServiceTicketImpl serviceTicket = new ServiceTicketImpl(WebContext.getAuthentication(),casDetails); - String ticket=ticketServices.createTicket(serviceTicket); + String ticket = ticketServices.createTicket(serviceTicket); StringBuffer callbackUrl = new StringBuffer(casDetails.getCallbackUrl()); if(casDetails.getCallbackUrl().indexOf("?")==-1) { @@ -158,7 +158,7 @@ public class CasAuthorizeEndpoint extends CasBaseAuthorizeEndpoint{ onlineTicketServices.store(onlineTicketId, onlineTicket); } - _logger.debug("redirect to CAS Client URL " + callbackUrl); + _logger.debug("redirect to CAS Client URL {}" , callbackUrl); ModelAndView modelAndView=new ModelAndView("authorize/cas_sso_submint"); modelAndView.addObject("callbackUrl", callbackUrl.toString()); diff --git a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/adapter/CasDefaultAdapter.java b/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/adapter/CasDefaultAdapter.java index 55a0aceb..5c595e00 100644 --- a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/adapter/CasDefaultAdapter.java +++ b/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/adapter/CasDefaultAdapter.java @@ -20,21 +20,25 @@ package org.maxkey.authz.cas.endpoint.adapter; import java.io.UnsupportedEncodingException; import org.apache.commons.codec.binary.Base64; -import org.maxkey.authn.SigninPrincipal; import org.maxkey.authz.cas.endpoint.response.ServiceResponseBuilder; import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; -import org.maxkey.entity.UserInfo; +import org.maxkey.entity.apps.AppsCasDetails; import org.maxkey.web.WebConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.web.servlet.ModelAndView; public class CasDefaultAdapter extends AbstractAuthorizeAdapter { + final static Logger _logger = LoggerFactory.getLogger(CasDefaultAdapter.class); static String Charset_UTF8="UTF-8"; + ServiceResponseBuilder serviceResponseBuilder; + @Override - public ModelAndView authorize(UserInfo userInfo, Object app, String data, ModelAndView modelAndView) { + public ModelAndView authorize(ModelAndView modelAndView) { - return null; + return modelAndView; } public String base64Attr(String attrValue){ @@ -48,8 +52,12 @@ public class CasDefaultAdapter extends AbstractAuthorizeAdapter { } @Override - public String generateInfo(SigninPrincipal authentication,UserInfo userInfo, Object serviceResponseObject) { - ServiceResponseBuilder serviceResponseBuilder=(ServiceResponseBuilder)serviceResponseObject; + public Object generateInfo() { + //user for return + String user = getValueByUserAttr(userInfo,((AppsCasDetails)this.app).getCasUser()); + _logger.debug("cas user {}",user); + serviceResponseBuilder.success().setUser(user); + //for user serviceResponseBuilder.setAttribute("uid", userInfo.getId()); serviceResponseBuilder.setAttribute("displayName", base64Attr(userInfo.getDisplayName())); @@ -69,7 +77,11 @@ public class CasDefaultAdapter extends AbstractAuthorizeAdapter { serviceResponseBuilder.setAttribute("institution", userInfo.getInstId()); serviceResponseBuilder.setAttribute(WebConstants.ONLINE_TICKET_NAME,authentication.getOnlineTicket().getTicketId()); - return null; + return serviceResponseBuilder; + } + + public void setServiceResponseBuilder(ServiceResponseBuilder serviceResponseBuilder) { + this.serviceResponseBuilder = serviceResponseBuilder; } } diff --git a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/ticket/st/RedisTicketServices.java b/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/ticket/st/RedisTicketServices.java index 53b760ef..e7636676 100644 --- a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/ticket/st/RedisTicketServices.java +++ b/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/ticket/st/RedisTicketServices.java @@ -53,15 +53,15 @@ public class RedisTicketServices extends RandomServiceTicketServices { @Override public void store(String ticketId, Ticket ticket) { RedisConnection conn=connectionFactory.getConnection(); - conn.setexObject(PREFIX+ticketId, serviceTicketValiditySeconds, ticket); + conn.setexObject(prefixTicketId(ticketId), serviceTicketValiditySeconds, ticket); conn.close(); } @Override public Ticket remove(String ticketId) { RedisConnection conn=connectionFactory.getConnection(); - Ticket ticket = conn.getObject(PREFIX+ticketId); - conn.delete(PREFIX+ticketId); + Ticket ticket = conn.getObject(prefixTicketId(ticketId)); + conn.delete(prefixTicketId(ticketId)); conn.close(); return ticket; } @@ -69,10 +69,14 @@ public class RedisTicketServices extends RandomServiceTicketServices { @Override public Ticket get(String ticketId) { RedisConnection conn=connectionFactory.getConnection(); - Ticket ticket = conn.getObject(PREFIX+ticketId); + Ticket ticket = conn.getObject(prefixTicketId(ticketId)); conn.close(); return ticket; } + + public String prefixTicketId(String ticketId) { + return PREFIX + ticketId; + } } diff --git a/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/ExtendApiAuthorizeEndpoint.java b/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/ExtendApiAuthorizeEndpoint.java index e1dfd9ea..49d4886c 100644 --- a/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/ExtendApiAuthorizeEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/ExtendApiAuthorizeEndpoint.java @@ -22,11 +22,11 @@ package org.maxkey.authz.exapi.endpoint; import javax.servlet.http.HttpServletRequest; +import org.maxkey.authn.SigninPrincipal; import org.maxkey.authz.endpoint.AuthorizeBaseEndpoint; import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; import org.maxkey.constants.ConstsBoolean; import org.maxkey.entity.Accounts; -import org.maxkey.entity.UserInfo; import org.maxkey.entity.apps.Apps; import org.maxkey.util.Instance; import org.maxkey.web.WebContext; @@ -54,53 +54,23 @@ public class ExtendApiAuthorizeEndpoint extends AuthorizeBaseEndpoint{ public ModelAndView authorize(HttpServletRequest request,@PathVariable("id") String id){ ModelAndView modelAndView=new ModelAndView("authorize/redirect_sso_submit"); - Apps apps=getApp(id); + Apps apps = getApp(id); _logger.debug(""+apps); - UserInfo userInfo = WebContext.getUserInfo(); if(ConstsBoolean.isTrue(apps.getIsAdapter())){ - - AbstractAuthorizeAdapter adapter =(AbstractAuthorizeAdapter)Instance.newInstance(apps.getAdapter()); - String username =""; - String password =""; - if(apps.getCredential()==1) { - if(apps.getSystemUserAttr().equalsIgnoreCase("userId")) { - username = userInfo.getId(); - }else if(apps.getSystemUserAttr().equalsIgnoreCase("username")) { - username = userInfo.getUsername(); - }else if(apps.getSystemUserAttr().equalsIgnoreCase("email")) { - username = userInfo.getEmail(); - }else if(apps.getSystemUserAttr().equalsIgnoreCase("employeeNumber")) { - username = userInfo.getEmployeeNumber(); - }else if(apps.getSystemUserAttr().equalsIgnoreCase("windowsaccount")) { - username = userInfo.getWindowsAccount(); - }else if(apps.getSystemUserAttr().equalsIgnoreCase("mobile")) { - username = userInfo.getMobile(); - }else if(apps.getSystemUserAttr().equalsIgnoreCase("workEmail")) { - username = userInfo.getWorkEmail(); - }else { - username = userInfo.getEmail(); - } - - } else if(apps.getCredential()==2) { - username = apps.getSharedUsername(); - password = apps.getSharedPassword(); - }else if(apps.getCredential()==3) { - Accounts appUser=getAccounts(apps); - if(appUser == null){ - return generateInitCredentialModelAndView(id,"/authorize/api/"+id); - } - apps.setAppUser(appUser); + AbstractAuthorizeAdapter adapter = (AbstractAuthorizeAdapter)Instance.newInstance(apps.getAdapter()); + Accounts account = getAccounts(apps); + if(apps.getCredential()==Apps.CREDENTIALS.USER_DEFINED && account == null) { + return generateInitCredentialModelAndView(id,"/authorize/api/"+id); } - modelAndView=adapter.authorize( - WebContext.getUserInfo(), - apps, - username+"="+password, - modelAndView); - return modelAndView; + adapter.setAuthentication((SigninPrincipal)WebContext.getAuthentication().getPrincipal()); + adapter.setUserInfo(WebContext.getUserInfo()); + adapter.setApp(apps); + adapter.setAccount(account); + + return adapter.authorize(modelAndView); }else{ - modelAndView.addObject("redirect_uri", getApp(id).getLoginUrl()); - + modelAndView.addObject("redirect_uri", apps.getLoginUrl()); return modelAndView; } diff --git a/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiCndnsApiMailAdapter.java b/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiCndnsApiMailAdapter.java index b15408aa..05e2469b 100644 --- a/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiCndnsApiMailAdapter.java +++ b/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiCndnsApiMailAdapter.java @@ -19,13 +19,12 @@ package org.maxkey.authz.exapi.endpoint.adapter; import java.time.Instant; import java.util.HashMap; -import org.maxkey.authn.SigninPrincipal; import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; import org.maxkey.client.http.HttpVerb; import org.maxkey.client.oauth.OAuthClient; import org.maxkey.crypto.DigestUtils; +import org.maxkey.entity.Accounts; import org.maxkey.entity.ExtraAttrs; -import org.maxkey.entity.UserInfo; import org.maxkey.entity.apps.Apps; import org.maxkey.util.HttpsTrusts; import org.maxkey.util.JsonUtils; @@ -45,6 +44,8 @@ public class ExtendApiCndnsApiMailAdapter extends AbstractAuthorizeAdapter { //sign with parameter //sign=md5(action=getUserInfo&appid=***&email=admin@maxkey.org&time=1579736456 + md5(token)) + Accounts account; + static String SIGN_STRING ="action=getDomainInfo&appid=%s%s"; static String SIGN_EMAIL_STRING ="action=getUserInfo&appid=%s&email=%s&time=%s%s"; @@ -55,18 +56,18 @@ public class ExtendApiCndnsApiMailAdapter extends AbstractAuthorizeAdapter { @Override - public String generateInfo(SigninPrincipal authentication,UserInfo userInfo,Object app) { + public Object generateInfo() { return null; } @Override - public String encrypt(String data, String algorithmKey, String algorithm) { + public Object encrypt(Object data, String algorithmKey, String algorithm) { return null; } @SuppressWarnings("unchecked") @Override - public ModelAndView authorize(UserInfo userInfo, Object app, String data,ModelAndView modelAndView) { + public ModelAndView authorize(ModelAndView modelAndView) { HttpsTrusts.beforeConnection(); Apps details=(Apps)app; diff --git a/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiQQExmailAdapter.java b/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiQQExmailAdapter.java index d8e90f3d..df84b0fb 100644 --- a/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiQQExmailAdapter.java +++ b/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiQQExmailAdapter.java @@ -18,12 +18,11 @@ package org.maxkey.authz.exapi.endpoint.adapter; import java.util.HashMap; -import org.maxkey.authn.SigninPrincipal; import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; import org.maxkey.client.oauth.OAuthClient; import org.maxkey.client.oauth.model.Token; +import org.maxkey.entity.Accounts; import org.maxkey.entity.ExtraAttrs; -import org.maxkey.entity.UserInfo; import org.maxkey.entity.apps.Apps; import org.maxkey.util.HttpsTrusts; import org.maxkey.util.JsonUtils; @@ -43,25 +42,20 @@ public class ExtendApiQQExmailAdapter extends AbstractAuthorizeAdapter { //https://exmail.qq.com/qy_mng_logic/doc#10036 static String AUTHKEY_URI="https://api.exmail.qq.com/cgi-bin/service/get_login_url?access_token=%s&userid=%s"; + Accounts account; + @Override - public String generateInfo(SigninPrincipal authentication,UserInfo userInfo,Object app) { + public Object generateInfo() { return null; } - @Override - public String encrypt(String data, String algorithmKey, String algorithm) { - return null; - } @SuppressWarnings("unchecked") @Override - public ModelAndView authorize(UserInfo userInfo, Object app, String data,ModelAndView modelAndView) { + public ModelAndView authorize(ModelAndView modelAndView) { HttpsTrusts.beforeConnection(); Apps details=(Apps)app; - String username = data.substring(0, data.indexOf("=")); - String password = data.substring(data.indexOf("=") + 1); - _logger.trace("username " + username +" password " + password); //extraAttrs from Applications ExtraAttrs extraAttrs=null; if(details.getIsExtendAttr()==1){ @@ -74,7 +68,7 @@ public class ExtendApiQQExmailAdapter extends AbstractAuthorizeAdapter { _logger.debug(""+token); OAuthClient authkeyRestClient=new OAuthClient( - String.format(AUTHKEY_URI,token.getAccess_token(),username)); + String.format(AUTHKEY_URI,token.getAccess_token(),userInfo.getUsername())); HashMap authKey=JsonUtils.gson2Object(authkeyRestClient.execute().getBody(), HashMap.class); _logger.debug("authKey : "+authKey); diff --git a/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiTimestampSignAdapter.java b/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiTimestampSignAdapter.java index 23f65509..e9827fe0 100644 --- a/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiTimestampSignAdapter.java +++ b/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiTimestampSignAdapter.java @@ -18,11 +18,10 @@ package org.maxkey.authz.exapi.endpoint.adapter; import java.time.Instant; -import org.maxkey.authn.SigninPrincipal; import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; import org.maxkey.crypto.DigestUtils; +import org.maxkey.entity.Accounts; import org.maxkey.entity.ExtraAttrs; -import org.maxkey.entity.UserInfo; import org.maxkey.entity.apps.Apps; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,18 +42,20 @@ import org.springframework.web.servlet.ModelAndView; public class ExtendApiTimestampSignAdapter extends AbstractAuthorizeAdapter { final static Logger _logger = LoggerFactory.getLogger(ExtendApiTimestampSignAdapter.class); + Accounts account; + @Override - public String generateInfo(SigninPrincipal authentication,UserInfo userInfo,Object app) { + public Object generateInfo() { return null; } @Override - public String encrypt(String data, String algorithmKey, String algorithm) { + public Object encrypt(Object data, String algorithmKey, String algorithm) { return null; } @Override - public ModelAndView authorize(UserInfo userInfo, Object app, String data,ModelAndView modelAndView) { + public ModelAndView authorize(ModelAndView modelAndView) { Apps details=(Apps)app; String code = details.getPrincipal(); diff --git a/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiZentaoAdapter.java b/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiZentaoAdapter.java index 8fbd89d3..eb7f8a86 100644 --- a/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiZentaoAdapter.java +++ b/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiZentaoAdapter.java @@ -18,11 +18,10 @@ package org.maxkey.authz.exapi.endpoint.adapter; import java.time.Instant; -import org.maxkey.authn.SigninPrincipal; import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; import org.maxkey.crypto.DigestUtils; +import org.maxkey.entity.Accounts; import org.maxkey.entity.ExtraAttrs; -import org.maxkey.entity.UserInfo; import org.maxkey.entity.apps.Apps; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,18 +43,20 @@ public class ExtendApiZentaoAdapter extends AbstractAuthorizeAdapter { static String login_url_template="api.php?m=user&f=apilogin&account=%s&code=%s&time=%s&token=%s"; static String login_url_m_template="account=%s&code=%s&time=%s&token=%s"; + Accounts account; + @Override - public String generateInfo(SigninPrincipal authentication,UserInfo userInfo,Object app) { + public Object generateInfo() { return null; } @Override - public String encrypt(String data, String algorithmKey, String algorithm) { + public Object encrypt(Object data, String algorithmKey, String algorithm) { return null; } @Override - public ModelAndView authorize(UserInfo userInfo, Object app, String data,ModelAndView modelAndView) { + public ModelAndView authorize(ModelAndView modelAndView) { Apps details=(Apps)app; //extraAttrs from Applications ExtraAttrs extraAttrs=null; diff --git a/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/FormBasedAuthorizeEndpoint.java b/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/FormBasedAuthorizeEndpoint.java index ff800762..5c6a4829 100644 --- a/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/FormBasedAuthorizeEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/FormBasedAuthorizeEndpoint.java @@ -22,6 +22,7 @@ package org.maxkey.authz.formbased.endpoint; import javax.servlet.http.HttpServletRequest; +import org.maxkey.authn.SigninPrincipal; import org.maxkey.authz.endpoint.AuthorizeBaseEndpoint; import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; import org.maxkey.authz.formbased.endpoint.adapter.FormBasedDefaultAdapter; @@ -62,40 +63,40 @@ public class FormBasedAuthorizeEndpoint extends AuthorizeBaseEndpoint{ public ModelAndView authorize( HttpServletRequest request, @PathVariable("id") String id){ - AppsFormBasedDetails formBasedDetails=formBasedDetailsService.getAppDetails(id); - _logger.debug(""+formBasedDetails); - Apps application= getApp(id); + + AppsFormBasedDetails formBasedDetails = formBasedDetailsService.getAppDetails(id); + _logger.debug("formBasedDetails {}",formBasedDetails); + Apps application = getApp(id); formBasedDetails.setAdapter(application.getAdapter()); formBasedDetails.setIsAdapter(application.getIsAdapter()); ModelAndView modelAndView=null; - Accounts appUser=getAccounts(formBasedDetails); + Accounts account = getAccounts(formBasedDetails); + _logger.debug("Accounts {}",account); - _logger.debug("Accounts "+appUser); - if(appUser == null){ + if(account == null){ return generateInitCredentialModelAndView(id,"/authz/formbased/"+id); - }else{ - formBasedDetails.setAppUser(appUser); - modelAndView=new ModelAndView(); AbstractAuthorizeAdapter adapter; if(ConstsBoolean.isTrue(formBasedDetails.getIsAdapter())){ - adapter =(AbstractAuthorizeAdapter)Instance.newInstance(formBasedDetails.getAdapter()); + Object formBasedAdapter = Instance.newInstance(formBasedDetails.getAdapter()); + adapter =(AbstractAuthorizeAdapter)formBasedAdapter; }else{ - adapter =(AbstractAuthorizeAdapter)defaultFormBasedAdapter; + FormBasedDefaultAdapter formBasedDefaultAdapter =new FormBasedDefaultAdapter(); + adapter =(AbstractAuthorizeAdapter)formBasedDefaultAdapter; } + adapter.setAuthentication((SigninPrincipal)WebContext.getAuthentication().getPrincipal()); + adapter.setUserInfo(WebContext.getUserInfo()); + adapter.setApp(formBasedDetails); + adapter.setAccount(account); - modelAndView=adapter.authorize( - WebContext.getUserInfo(), - formBasedDetails, - appUser.getRelatedUsername()+"."+appUser.getRelatedPassword(), - modelAndView); + modelAndView = adapter.authorize(modelAndView); } - _logger.debug("FormBased View Name " + modelAndView.getViewName()); + _logger.debug("FormBased View Name {}" , modelAndView.getViewName()); return modelAndView; } diff --git a/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedDefaultAdapter.java b/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedDefaultAdapter.java index 2beda9a5..74481cd8 100644 --- a/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedDefaultAdapter.java +++ b/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedDefaultAdapter.java @@ -19,37 +19,30 @@ package org.maxkey.authz.formbased.endpoint.adapter; import java.time.Instant; -import org.maxkey.authn.SigninPrincipal; import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; import org.maxkey.constants.ConstsBoolean; import org.maxkey.crypto.DigestUtils; -import org.maxkey.entity.UserInfo; import org.maxkey.entity.apps.AppsFormBasedDetails; import org.springframework.web.servlet.ModelAndView; public class FormBasedDefaultAdapter extends AbstractAuthorizeAdapter { @Override - public String generateInfo(SigninPrincipal authentication,UserInfo userInfo,Object app) { + public Object generateInfo() { return null; } - + @Override - public String encrypt(String data, String algorithmKey, String algorithm) { - return null; - } - - @Override - public ModelAndView authorize(UserInfo userInfo, Object app, String data,ModelAndView modelAndView) { + public ModelAndView authorize(ModelAndView modelAndView) { modelAndView.setViewName("authorize/formbased_sso_submint"); AppsFormBasedDetails details=(AppsFormBasedDetails)app; - String password = details.getAppUser().getRelatedPassword(); + String password = account.getRelatedPassword(); if(null==details.getPasswordAlgorithm()||details.getPasswordAlgorithm().equals("")){ }else if(details.getPasswordAlgorithm().indexOf("HEX")>-1){ - password = DigestUtils.digestHex(details.getAppUser().getRelatedPassword(),details.getPasswordAlgorithm().substring(0, details.getPasswordAlgorithm().indexOf("HEX"))); + password = DigestUtils.digestHex(account.getRelatedPassword(),details.getPasswordAlgorithm().substring(0, details.getPasswordAlgorithm().indexOf("HEX"))); }else{ - password = DigestUtils.digestBase64(details.getAppUser().getRelatedPassword(),details.getPasswordAlgorithm()); + password = DigestUtils.digestBase64(account.getRelatedPassword(),details.getPasswordAlgorithm()); } modelAndView.addObject("id", details.getId()); @@ -58,9 +51,9 @@ public class FormBasedDefaultAdapter extends AbstractAuthorizeAdapter { modelAndView.addObject("loginUrl", details.getLoginUrl()); modelAndView.addObject("usernameMapping", details.getUsernameMapping()); modelAndView.addObject("passwordMapping", details.getPasswordMapping()); - modelAndView.addObject("username", details.getAppUser().getRelatedUsername()); + modelAndView.addObject("username", account.getRelatedUsername()); modelAndView.addObject("password", password); - modelAndView.addObject("timestamp", ""+Instant.now().getEpochSecond()); + modelAndView.addObject("timestamp", "" + Instant.now().getEpochSecond()); if(ConstsBoolean.isTrue(details.getIsExtendAttr())){ modelAndView.addObject("extendAttr", details.getExtendAttr()); diff --git a/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedNetease163EmailAdapter.java b/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedNetease163EmailAdapter.java index ea0e589d..ea19641d 100644 --- a/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedNetease163EmailAdapter.java +++ b/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedNetease163EmailAdapter.java @@ -17,32 +17,25 @@ package org.maxkey.authz.formbased.endpoint.adapter; -import org.maxkey.authn.SigninPrincipal; import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; import org.maxkey.constants.ConstsBoolean; -import org.maxkey.entity.UserInfo; import org.maxkey.entity.apps.AppsFormBasedDetails; import org.springframework.web.servlet.ModelAndView; public class FormBasedNetease163EmailAdapter extends AbstractAuthorizeAdapter { - + @Override - public String generateInfo(SigninPrincipal authentication,UserInfo userInfo,Object app) { + public String generateInfo() { return null; } @Override - public String encrypt(String data, String algorithmKey, String algorithm) { - return null; - } - - @Override - public ModelAndView authorize(UserInfo userInfo, Object app, String data,ModelAndView modelAndView) { + public ModelAndView authorize(ModelAndView modelAndView) { modelAndView.setViewName("authorize/formbased_163email_sso_submint"); AppsFormBasedDetails details=(AppsFormBasedDetails)app; - modelAndView.addObject("username", details.getAppUser().getRelatedUsername().substring(details.getAppUser().getRelatedUsername().indexOf("@"))); - modelAndView.addObject("email", details.getAppUser().getRelatedUsername()); - modelAndView.addObject("password", details.getAppUser().getRelatedPassword()); + modelAndView.addObject("username", account.getRelatedUsername().substring(account.getRelatedUsername().indexOf("@"))); + modelAndView.addObject("email", account.getRelatedUsername()); + modelAndView.addObject("password", account.getRelatedPassword()); if(ConstsBoolean.isTrue(details.getIsExtendAttr())){ modelAndView.addObject("extendAttr", details.getExtendAttr()); diff --git a/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedNeteaseNoteYoudaoAdapter.java b/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedNeteaseNoteYoudaoAdapter.java index 0f05a8a3..7b37562b 100644 --- a/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedNeteaseNoteYoudaoAdapter.java +++ b/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedNeteaseNoteYoudaoAdapter.java @@ -19,45 +19,26 @@ package org.maxkey.authz.formbased.endpoint.adapter; import java.util.Date; -import org.maxkey.authn.SigninPrincipal; import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; import org.maxkey.crypto.DigestUtils; -import org.maxkey.entity.UserInfo; import org.maxkey.entity.apps.AppsFormBasedDetails; import org.springframework.web.servlet.ModelAndView; public class FormBasedNeteaseNoteYoudaoAdapter extends AbstractAuthorizeAdapter { @Override - public String generateInfo(SigninPrincipal authentication,UserInfo userInfo,Object app) { + public Object generateInfo() { return null; } - @Override - public String encrypt(String data, String algorithmKey, String algorithm) { - return null; - } @Override - public ModelAndView authorize(UserInfo userInfo, Object app, String data,ModelAndView modelAndView) { + public ModelAndView authorize(ModelAndView modelAndView) { modelAndView.setViewName("authorize/formbased_wy_youdao_sso_submint"); AppsFormBasedDetails details=(AppsFormBasedDetails)app; - modelAndView.addObject("username", details.getAppUser().getRelatedUsername()); - modelAndView.addObject("password", DigestUtils.md5Hex(details.getAppUser().getRelatedPassword())); + modelAndView.addObject("username", account.getRelatedUsername()); + modelAndView.addObject("password", DigestUtils.md5Hex(account.getRelatedPassword())); modelAndView.addObject("currentTime", (new Date()).getTime()); - - /* - if(BOOLEAN.isTrue(details.getIsExtendAttr())){ - modelAndView.addObject("extendAttr", details.getExtendAttr()); - modelAndView.addObject("isExtendAttr", true); - }else{ - modelAndView.addObject("isExtendAttr", false); - } - - modelAndView.addObject("action", details.getRedirectUri()); - modelAndView.addObject("usernameMapping", details.getUsernameMapping()); - modelAndView.addObject("passwordMapping", details.getPasswordMapping()); - */ return modelAndView; } diff --git a/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedRedirectAdapter.java b/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedRedirectAdapter.java index 77ee62fd..f86d61b6 100644 --- a/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedRedirectAdapter.java +++ b/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedRedirectAdapter.java @@ -19,11 +19,9 @@ package org.maxkey.authz.formbased.endpoint.adapter; import java.time.Instant; -import org.maxkey.authn.SigninPrincipal; import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; import org.maxkey.constants.ConstsBoolean; import org.maxkey.crypto.DigestUtils; -import org.maxkey.entity.UserInfo; import org.maxkey.entity.apps.AppsFormBasedDetails; import org.maxkey.web.WebContext; import org.springframework.web.servlet.ModelAndView; @@ -31,26 +29,21 @@ import org.springframework.web.servlet.ModelAndView; public class FormBasedRedirectAdapter extends AbstractAuthorizeAdapter { @Override - public String generateInfo(SigninPrincipal authentication,UserInfo userInfo,Object app) { + public Object generateInfo() { return null; } @Override - public String encrypt(String data, String algorithmKey, String algorithm) { - return null; - } - - @Override - public ModelAndView authorize(UserInfo userInfo, Object app, String data,ModelAndView modelAndView) { + public ModelAndView authorize(ModelAndView modelAndView) { modelAndView.setViewName("authorize/formbased_redirect_submint"); AppsFormBasedDetails details=(AppsFormBasedDetails)app; - String password = details.getAppUser().getRelatedPassword(); + String password = account.getRelatedPassword(); if(null==details.getPasswordAlgorithm()||details.getPasswordAlgorithm().equals("")){ }else if(details.getPasswordAlgorithm().indexOf("HEX")>-1){ - password = DigestUtils.digestHex(details.getAppUser().getRelatedPassword(),details.getPasswordAlgorithm().substring(0, details.getPasswordAlgorithm().indexOf("HEX"))); + password = DigestUtils.digestHex(account.getRelatedPassword(),details.getPasswordAlgorithm().substring(0, details.getPasswordAlgorithm().indexOf("HEX"))); }else{ - password = DigestUtils.digestBase64(details.getAppUser().getRelatedPassword(),details.getPasswordAlgorithm()); + password = DigestUtils.digestBase64(account.getRelatedPassword(),details.getPasswordAlgorithm()); } modelAndView.addObject("id", details.getId()); @@ -59,7 +52,7 @@ public class FormBasedRedirectAdapter extends AbstractAuthorizeAdapter { modelAndView.addObject("loginUrl", details.getLoginUrl()); modelAndView.addObject("usernameMapping", details.getUsernameMapping()); modelAndView.addObject("passwordMapping", details.getPasswordMapping()); - modelAndView.addObject("username", details.getAppUser().getRelatedUsername()); + modelAndView.addObject("username", account.getRelatedUsername()); modelAndView.addObject("password", password); modelAndView.addObject("timestamp", ""+Instant.now().getEpochSecond()); diff --git a/maxkey-protocols/maxkey-protocol-jwt/src/main/java/org/maxkey/authz/jwt/endpoint/adapter/JwtAdapter.java b/maxkey-protocols/maxkey-protocol-jwt/src/main/java/org/maxkey/authz/jwt/endpoint/adapter/JwtAdapter.java index 06ebb703..bf09e3fe 100644 --- a/maxkey-protocols/maxkey-protocol-jwt/src/main/java/org/maxkey/authz/jwt/endpoint/adapter/JwtAdapter.java +++ b/maxkey-protocols/maxkey-protocol-jwt/src/main/java/org/maxkey/authz/jwt/endpoint/adapter/JwtAdapter.java @@ -17,26 +17,31 @@ package org.maxkey.authz.jwt.endpoint.adapter; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; import java.util.Arrays; import java.util.Date; import java.util.UUID; import org.joda.time.DateTime; -import org.maxkey.authn.SigninPrincipal; import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; -import org.maxkey.configuration.oidc.OIDCProviderMetadata; -import org.maxkey.crypto.jwt.signer.service.JwtSigningAndValidationService; -import org.maxkey.entity.UserInfo; -import org.maxkey.entity.apps.Apps; +import org.maxkey.crypto.jose.keystore.JWKSetKeyStore; +import org.maxkey.crypto.jwt.encryption.service.impl.DefaultJwtEncryptionAndDecryptionService; +import org.maxkey.crypto.jwt.signer.service.impl.DefaultJwtSigningAndValidationService; import org.maxkey.entity.apps.AppsJwtDetails; import org.maxkey.web.WebConstants; -import org.maxkey.web.WebContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.servlet.ModelAndView; +import com.nimbusds.jose.EncryptionMethod; +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.JWEAlgorithm; +import com.nimbusds.jose.JWEHeader; +import com.nimbusds.jose.JWEObject; import com.nimbusds.jose.JWSAlgorithm; import com.nimbusds.jose.JWSHeader; +import com.nimbusds.jose.Payload; import com.nimbusds.jwt.JWT; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.PlainJWT; @@ -44,23 +49,35 @@ import com.nimbusds.jwt.SignedJWT; public class JwtAdapter extends AbstractAuthorizeAdapter { final static Logger _logger = LoggerFactory.getLogger(JwtAdapter.class); + + AppsJwtDetails jwtDetails; + + JWT jwtToken; + + JWEObject jweObject; + + JWTClaimsSet jwtClaims; + + public JwtAdapter() { + + } + + public JwtAdapter(AppsJwtDetails jwtDetails) { + this.jwtDetails = jwtDetails; + } + @Override - public String generateInfo(SigninPrincipal authentication,UserInfo userInfo,Object app) { - AppsJwtDetails details=(AppsJwtDetails)app; - + public Object generateInfo() { + DateTime currentDateTime = DateTime.now(); + Date expirationTime = currentDateTime.plusMinutes(Integer.parseInt(jwtDetails.getExpires())).toDate(); + _logger.debug("expiration Time : {}" , expirationTime); + String subject = getValueByUserAttr(userInfo,jwtDetails.getSubject()); + _logger.trace("jwt subject : {}" , subject); - JwtSigningAndValidationService jwtSignerService= WebContext.getBean("jwtSignerValidationService",JwtSigningAndValidationService.class); - OIDCProviderMetadata providerMetadata= WebContext.getBean("oidcProviderMetadata",OIDCProviderMetadata.class); - - DateTime currentDateTime=DateTime.now(); - - Date expirationTime=currentDateTime.plusMinutes(Integer.parseInt(details.getExpires())).toDate(); - _logger.debug("expiration Time : "+expirationTime); - - JWTClaimsSet jwtClaims =new JWTClaimsSet.Builder() - .issuer(providerMetadata.getIssuer()) - .subject(userInfo.getUsername()) - .audience(Arrays.asList(details.getId())) + jwtClaims =new JWTClaimsSet.Builder() + .issuer(jwtDetails.getIssuer()) + .subject(subject) + .audience(Arrays.asList(jwtDetails.getId())) .jwtID(UUID.randomUUID().toString()) .issueTime(currentDateTime.toDate()) .expirationTime(expirationTime) @@ -70,58 +87,111 @@ public class JwtAdapter extends AbstractAuthorizeAdapter { .claim("external_id", userInfo.getId()) .claim("locale", userInfo.getLocale()) .claim(WebConstants.ONLINE_TICKET_NAME, authentication.getOnlineTicket().getTicketId()) - .claim("kid", jwtSignerService.getDefaultSignerKeyId()) + .claim("kid", jwtDetails.getId()+ "_sig") .claim("institution", userInfo.getInstId()) .build(); - _logger.debug("jwt Claims : "+jwtClaims); + _logger.trace("jwt Claims : {}" , jwtClaims); - JWT jwtToken = new PlainJWT(jwtClaims); - - JWSAlgorithm signingAlg = jwtSignerService.getDefaultSigningAlgorithm(); - - //get PublicKey - /*Map jwkMap=jwtSignerService.getAllPublicKeys(); - - JWK jwk=jwkMap.get("connsec_rsa1"); - - _logger.debug("isPrivate "+jwk.isPrivate());*/ - - _logger.debug(" signingAlg "+signingAlg); - - jwtToken = new SignedJWT(new JWSHeader(signingAlg), jwtClaims); - // sign it with the server's key - jwtSignerService.signJwt((SignedJWT) jwtToken); - - String tokenString=jwtToken.serialize(); - _logger.debug("jwt Token : "+tokenString); - - return tokenString; + jwtToken = new PlainJWT(jwtClaims); + + return jwtToken; } @Override - public String encrypt(String data, String algorithmKey, String algorithm) { + public Object sign(Object data,String signatureKey,String signature) { + if(!jwtDetails.getSignature().equalsIgnoreCase("none")) { + JWKSetKeyStore jwkSetKeyStore = new JWKSetKeyStore("{\"keys\": ["+jwtDetails.getSignatureKey()+"]}"); + try { + DefaultJwtSigningAndValidationService jwtSignerService = + new DefaultJwtSigningAndValidationService(jwkSetKeyStore); + jwtSignerService.setDefaultSignerKeyId(jwtDetails.getId() + "_sig"); + jwtSignerService.setDefaultSigningAlgorithmName(jwtDetails.getSignature()); + JWSAlgorithm signingAlg = jwtSignerService.getDefaultSigningAlgorithm(); + _logger.trace(" signingAlg {}" , signingAlg); + jwtToken = new SignedJWT(new JWSHeader(signingAlg), jwtClaims); + // sign it with the server's key + jwtSignerService.signJwt((SignedJWT) jwtToken); + return jwtToken; + } catch (NoSuchAlgorithmException e) { + _logger.error("NoSuchAlgorithmException", e); + } catch (InvalidKeySpecException e) { + _logger.error("InvalidKeySpecException", e); + } catch (JOSEException e) { + _logger.error("JOSEException", e); + } + } return data; } @Override - public String sign(String data, Apps app) { - + public Object encrypt(Object data, String algorithmKey, String algorithm) { + if(!jwtDetails.getAlgorithm().equalsIgnoreCase("none")) { + JWKSetKeyStore jwkSetKeyStore = new JWKSetKeyStore("{\"keys\": ["+jwtDetails.getAlgorithmKey()+"]}"); + try { + DefaultJwtEncryptionAndDecryptionService jwtEncryptionService = + new DefaultJwtEncryptionAndDecryptionService(jwkSetKeyStore); + jwtEncryptionService.setDefaultEncryptionKeyId(jwtDetails.getId() + "_enc"); + jwtEncryptionService.setDefaultAlgorithm(jwtDetails.getAlgorithm()); + JWEAlgorithm encryptAlgorithm = null; + if(jwtDetails.getAlgorithm().startsWith("RSA")) { + encryptAlgorithm = jwtEncryptionService.getDefaultAlgorithm(); + }else { + encryptAlgorithm = JWEAlgorithm.DIR; + } + _logger.trace(" encryptAlgorithm {}" , encryptAlgorithm); + EncryptionMethod encryptionMethod = + jwtEncryptionService.parseEncryptionMethod(jwtDetails.getEncryptionMethod()); + + Payload payload; + if(jwtToken instanceof SignedJWT) { + payload = ((SignedJWT)jwtToken).getPayload(); + }else { + payload = ((PlainJWT)jwtToken).getPayload(); + } + // Example Request JWT encrypted with RSA-OAEP-256 and 128-bit AES/GCM + //JWEHeader jweHeader = new JWEHeader(JWEAlgorithm.RSA1_5, EncryptionMethod.A128GCM); + + jweObject = new JWEObject( + new JWEHeader.Builder(new JWEHeader(encryptAlgorithm,encryptionMethod)) + .contentType("JWT") // required to indicate nested JWT + .build(), + payload); + + jwtEncryptionService.encryptJwt(jweObject); + + } catch (NoSuchAlgorithmException | InvalidKeySpecException | JOSEException e) { + _logger.error("Encrypt Exception", e); + } + } return data; } - + @Override - public ModelAndView authorize(UserInfo userInfo, Object app, String data,ModelAndView modelAndView) { + public ModelAndView authorize(ModelAndView modelAndView) { modelAndView.setViewName("authorize/jwt_sso_submint"); - AppsJwtDetails details=(AppsJwtDetails)app; - modelAndView.addObject("action", details.getRedirectUri()); - _logger.debug("jwt Token data : "+data); + modelAndView.addObject("action", jwtDetails.getRedirectUri()); - modelAndView.addObject("token",data); - - //return_to + modelAndView.addObject("token",serialize()); + modelAndView.addObject("jwtName",jwtDetails.getJwtName()); return modelAndView; } + public void setJwtDetails(AppsJwtDetails jwtDetails) { + this.jwtDetails = jwtDetails; + } + + @Override + public String serialize() { + String tokenString = ""; + if(jweObject != null) { + tokenString = jweObject.serialize(); + }else { + tokenString = jwtToken.serialize(); + } + _logger.debug("jwt Token : {}" , tokenString); + return tokenString; + } + } diff --git a/maxkey-protocols/maxkey-protocol-jwt/src/main/java/org/maxkey/authz/jwt/endpoint/adapter/JwtDefaultAdapter.java b/maxkey-protocols/maxkey-protocol-jwt/src/main/java/org/maxkey/authz/jwt/endpoint/adapter/JwtDefaultAdapter.java deleted file mode 100644 index 3f35148b..00000000 --- a/maxkey-protocols/maxkey-protocol-jwt/src/main/java/org/maxkey/authz/jwt/endpoint/adapter/JwtDefaultAdapter.java +++ /dev/null @@ -1,115 +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.authz.jwt.endpoint.adapter; - -import java.util.Arrays; -import java.util.Date; -import java.util.UUID; - -import org.joda.time.DateTime; -import org.maxkey.authn.SigninPrincipal; -import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; -import org.maxkey.configuration.oidc.OIDCProviderMetadata; -import org.maxkey.crypto.jwt.signer.service.JwtSigningAndValidationService; -import org.maxkey.entity.UserInfo; -import org.maxkey.entity.apps.AppsJwtDetails; -import org.maxkey.web.WebConstants; -import org.maxkey.web.WebContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.web.servlet.ModelAndView; - -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jose.JWSHeader; -import com.nimbusds.jwt.JWT; -import com.nimbusds.jwt.JWTClaimsSet; -import com.nimbusds.jwt.PlainJWT; -import com.nimbusds.jwt.SignedJWT; - -public class JwtDefaultAdapter extends AbstractAuthorizeAdapter { - final static Logger _logger = LoggerFactory.getLogger(JwtDefaultAdapter.class); - @Override - public String generateInfo(SigninPrincipal authentication,UserInfo userInfo,Object app) { - AppsJwtDetails details=(AppsJwtDetails)app; - - - JwtSigningAndValidationService jwtSignerService= WebContext.getBean("jwtSignerValidationService",JwtSigningAndValidationService.class); - OIDCProviderMetadata providerMetadata= WebContext.getBean("oidcProviderMetadata",OIDCProviderMetadata.class); - - DateTime currentDateTime=DateTime.now(); - - Date expirationTime=currentDateTime.plusMinutes(Integer.parseInt(details.getExpires())).toDate(); - _logger.debug("expiration Time : "+expirationTime); - - JWTClaimsSet jwtClaims =new JWTClaimsSet.Builder() - .issuer(providerMetadata.getIssuer()) - .subject(userInfo.getUsername()) - .audience(Arrays.asList(details.getId())) - .jwtID(UUID.randomUUID().toString()) - .issueTime(currentDateTime.toDate()) - .expirationTime(expirationTime) - .claim("email", userInfo.getWorkEmail()) - .claim("name", userInfo.getUsername()) - .claim("user_id", userInfo.getId()) - .claim("external_id", userInfo.getId()) - .claim("locale", userInfo.getLocale()) - .claim(WebConstants.ONLINE_TICKET_NAME, authentication.getOnlineTicket().getTicketId()) - .claim("kid", jwtSignerService.getDefaultSignerKeyId()) - .claim("institution", userInfo.getInstId()) - .build(); - - _logger.debug("jwt Claims : "+jwtClaims); - - JWT jwtToken = new PlainJWT(jwtClaims); - - JWSAlgorithm signingAlg = jwtSignerService.getDefaultSigningAlgorithm(); - - //get PublicKey - /*Map jwkMap=jwtSignerService.getAllPublicKeys(); - - JWK jwk=jwkMap.get("connsec_rsa1"); - - _logger.debug("isPrivate "+jwk.isPrivate());*/ - - _logger.debug(" signingAlg "+signingAlg); - - jwtToken = new SignedJWT(new JWSHeader(signingAlg), jwtClaims); - // sign it with the server's key - jwtSignerService.signJwt((SignedJWT) jwtToken); - - String tokenString=jwtToken.serialize(); - _logger.debug("jwt Token : "+tokenString); - - return tokenString; - } - - @Override - public String encrypt(String data, String algorithmKey, String algorithm) { - return super.encrypt(data, algorithmKey, algorithm); - } - - @Override - public ModelAndView authorize(UserInfo userInfo, Object app, String data,ModelAndView modelAndView) { - modelAndView.setViewName("authorize/jwt_sso_submint"); - AppsJwtDetails details=(AppsJwtDetails)app; - modelAndView.addObject("action", details.getRedirectUri()); - - modelAndView.addObject("token",data ); - return modelAndView; - } -} diff --git a/maxkey-protocols/maxkey-protocol-jwt/src/main/java/org/maxkey/authz/jwt/endpoint/adapter/JwtHS256Adapter.java b/maxkey-protocols/maxkey-protocol-jwt/src/main/java/org/maxkey/authz/jwt/endpoint/adapter/JwtHS256Adapter.java deleted file mode 100644 index d71ede13..00000000 --- a/maxkey-protocols/maxkey-protocol-jwt/src/main/java/org/maxkey/authz/jwt/endpoint/adapter/JwtHS256Adapter.java +++ /dev/null @@ -1,124 +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.authz.jwt.endpoint.adapter; - -import java.util.Arrays; -import java.util.Date; -import java.util.UUID; - -import org.joda.time.DateTime; -import org.maxkey.authn.SigninPrincipal; -import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; -import org.maxkey.configuration.oidc.OIDCProviderMetadata; -import org.maxkey.crypto.jwt.signer.service.JwtSigningAndValidationService; -import org.maxkey.crypto.jwt.signer.service.impl.SymmetricSigningAndValidationServiceBuilder; -import org.maxkey.crypto.password.PasswordReciprocal; -import org.maxkey.entity.UserInfo; -import org.maxkey.entity.apps.Apps; -import org.maxkey.entity.apps.AppsJwtDetails; -import org.maxkey.web.WebConstants; -import org.maxkey.web.WebContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.web.servlet.ModelAndView; - -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jose.JWSHeader; -import com.nimbusds.jwt.JWT; -import com.nimbusds.jwt.JWTClaimsSet; -import com.nimbusds.jwt.PlainJWT; -import com.nimbusds.jwt.SignedJWT; - -public class JwtHS256Adapter extends AbstractAuthorizeAdapter { - final static Logger _logger = LoggerFactory.getLogger(JwtHS256Adapter.class); - private SymmetricSigningAndValidationServiceBuilder symmetricJwtSignerServiceBuilder=new SymmetricSigningAndValidationServiceBuilder(); - - @Override - public String generateInfo(SigninPrincipal authentication,UserInfo userInfo,Object app) { - AppsJwtDetails details=(AppsJwtDetails)app; - - OIDCProviderMetadata providerMetadata= WebContext.getBean("oidcProviderMetadata",OIDCProviderMetadata.class); - - DateTime currentDateTime=DateTime.now(); - - Date expirationTime=currentDateTime.plusMinutes(Integer.parseInt(details.getExpires())).toDate(); - _logger.debug("expiration Time : "+expirationTime); - - JWTClaimsSet jwtClaims =new JWTClaimsSet.Builder() - .issuer(providerMetadata.getIssuer()) - .subject(userInfo.getUsername()) - .audience(Arrays.asList(details.getId())) - .jwtID(UUID.randomUUID().toString()) - .issueTime(currentDateTime.toDate()) - .expirationTime(expirationTime) - .claim("email", userInfo.getWorkEmail()) - .claim("name", userInfo.getUsername()) - .claim("user_id", userInfo.getId()) - .claim(WebConstants.ONLINE_TICKET_NAME, authentication.getOnlineTicket().getTicketId()) - .claim("external_id", userInfo.getId()) - .claim("locale", userInfo.getLocale()) - .claim("kid", "SYMMETRIC-KEY") - .claim("institution", userInfo.getInstId()) - .build(); - - _logger.debug("jwt Claims : "+jwtClaims); - - JWT jwtToken = new PlainJWT(jwtClaims); - - String sharedSecret=PasswordReciprocal.getInstance().decoder(details.getAlgorithmKey()); - - _logger.debug("jwt sharedSecret : "+sharedSecret); - - JwtSigningAndValidationService symmetricJwtSignerService =symmetricJwtSignerServiceBuilder.serviceBuilder(sharedSecret); - if(symmetricJwtSignerService!=null){ - jwtToken = new SignedJWT(new JWSHeader(JWSAlgorithm.HS256), jwtClaims); - symmetricJwtSignerService.signJwt((SignedJWT) jwtToken); - } - - String tokenString=jwtToken.serialize(); - _logger.debug("jwt Token : "+tokenString); - - return tokenString; - } - - @Override - public String encrypt(String data, String algorithmKey, String algorithm) { - return data; - } - - @Override - public String sign(String data, Apps app) { - - return data; - } - - @Override - public ModelAndView authorize(UserInfo userInfo, Object app, String data,ModelAndView modelAndView) { - modelAndView.setViewName("authorize/jwt_sso_submint"); - AppsJwtDetails details=(AppsJwtDetails)app; - modelAndView.addObject("action", details.getRedirectUri()); - _logger.debug("jwt Token data : "+data); - - modelAndView.addObject("token",data); - - //return_to - - return modelAndView; - } - -} diff --git a/maxkey-protocols/maxkey-protocol-jwt/src/main/java/org/maxkey/authz/token/endpoint/JwtAuthorizeEndpoint.java b/maxkey-protocols/maxkey-protocol-jwt/src/main/java/org/maxkey/authz/token/endpoint/JwtAuthorizeEndpoint.java index c77f94d3..a5eabbe9 100644 --- a/maxkey-protocols/maxkey-protocol-jwt/src/main/java/org/maxkey/authz/token/endpoint/JwtAuthorizeEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-jwt/src/main/java/org/maxkey/authz/token/endpoint/JwtAuthorizeEndpoint.java @@ -20,14 +20,17 @@ */ package org.maxkey.authz.token.endpoint; +import java.lang.reflect.InvocationTargetException; + import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.beanutils.BeanUtils; import org.maxkey.authn.SigninPrincipal; import org.maxkey.authz.endpoint.AuthorizeBaseEndpoint; import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; -import org.maxkey.authz.jwt.endpoint.adapter.JwtDefaultAdapter; +import org.maxkey.authz.jwt.endpoint.adapter.JwtAdapter; import org.maxkey.configuration.ApplicationConfig; import org.maxkey.constants.ConstsBoolean; import org.maxkey.entity.apps.Apps; @@ -59,8 +62,6 @@ public class JwtAuthorizeEndpoint extends AuthorizeBaseEndpoint{ @Autowired AppsJwtDetailsService jwtDetailsService; - JwtDefaultAdapter jwtDefaultAdapter=new JwtDefaultAdapter(); - @Autowired ApplicationConfig applicationConfig; @@ -83,44 +84,36 @@ public class JwtAuthorizeEndpoint extends AuthorizeBaseEndpoint{ AbstractAuthorizeAdapter adapter; if(ConstsBoolean.isTrue(jwtDetails.getIsAdapter())){ - adapter =(AbstractAuthorizeAdapter)Instance.newInstance(jwtDetails.getAdapter()); + Object jwtAdapter = Instance.newInstance(jwtDetails.getAdapter()); + try { + BeanUtils.setProperty(jwtAdapter, "jwtDetails", jwtDetails); + } catch (IllegalAccessException | InvocationTargetException e) { + _logger.error("setProperty error . ", e); + } + adapter = (AbstractAuthorizeAdapter)jwtAdapter; }else{ - adapter =(AbstractAuthorizeAdapter)jwtDefaultAdapter; + JwtAdapter jwtAdapter =new JwtAdapter(jwtDetails); + adapter = (AbstractAuthorizeAdapter)jwtAdapter; } - String tokenData=adapter.generateInfo( - (SigninPrincipal)WebContext.getAuthentication().getPrincipal(), - WebContext.getUserInfo(), - jwtDetails); + adapter.setAuthentication((SigninPrincipal)WebContext.getAuthentication().getPrincipal()); + adapter.setUserInfo(WebContext.getUserInfo()); - String encryptTokenData=adapter.encrypt( - tokenData, - jwtDetails.getAlgorithmKey(), - jwtDetails.getAlgorithm()); - - String signTokenData=adapter.sign( - encryptTokenData, - jwtDetails); + adapter.generateInfo(); + //sign + adapter.sign(null,jwtDetails.getSignatureKey(), jwtDetails.getSignature()); + //encrypt + adapter.encrypt(null, jwtDetails.getAlgorithmKey(), jwtDetails.getAlgorithm()); if(jwtDetails.getTokenType().equalsIgnoreCase("POST")) { - modelAndView=adapter.authorize( - WebContext.getUserInfo(), - jwtDetails, - signTokenData, - modelAndView); - - return modelAndView; + return adapter.authorize(modelAndView); }else { + _logger.debug("Cookie Name : {}" , jwtDetails.getJwtName()); - String cookieValue=""; - cookieValue=signTokenData; + Cookie cookie= new Cookie(jwtDetails.getJwtName(),adapter.serialize()); - _logger.debug("Cookie Name : "+jwtDetails.getCookieName()); - - Cookie cookie= new Cookie(jwtDetails.getCookieName(),cookieValue); - - Integer maxAge=Integer.parseInt(jwtDetails.getExpires())*60; - _logger.debug("Cookie Max Age :"+maxAge+" seconds."); + Integer maxAge = Integer.parseInt(jwtDetails.getExpires()) * 60; + _logger.debug("Cookie Max Age : {} seconds." , maxAge); cookie.setMaxAge(maxAge); cookie.setPath("/"); @@ -129,7 +122,7 @@ public class JwtAuthorizeEndpoint extends AuthorizeBaseEndpoint{ //tomcat 8.5 cookie.setDomain(applicationConfig.getBaseDomainName()); - _logger.debug("Sub Domain Name : "+"."+applicationConfig.getBaseDomainName()); + _logger.debug("Sub Domain Name : .{}",applicationConfig.getBaseDomainName()); response.addCookie(cookie); if(jwtDetails.getRedirectUri().indexOf(applicationConfig.getBaseDomainName())>-1){ diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/ClientDetailsService.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/ClientDetailsService.java index f751ae7a..b3d2518e 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/ClientDetailsService.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/ClientDetailsService.java @@ -32,6 +32,6 @@ public interface ClientDetailsService { * @return The client details (never null). * @throws ClientRegistrationException If the client account is locked, expired, disabled, or invalid for any other reason. */ - ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException; + ClientDetails loadClientByClientId(String clientId,boolean cached) throws ClientRegistrationException; } \ No newline at end of file diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/ApprovalStoreUserApprovalHandler.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/ApprovalStoreUserApprovalHandler.java index 76fdd35f..d29000af 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/ApprovalStoreUserApprovalHandler.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/ApprovalStoreUserApprovalHandler.java @@ -111,7 +111,7 @@ public class ApprovalStoreUserApprovalHandler implements UserApprovalHandler, In if (clientDetailsService != null) { try { - ClientDetails client = clientDetailsService.loadClientByClientId(clientId); + ClientDetails client = clientDetailsService.loadClientByClientId(clientId,true); for (String scope : requestedScopes) { if (client.isAutoApprove(scope) || client.isAutoApprove("all")) { approvedScopes.add(scope); diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/TokenStoreUserApprovalHandler.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/TokenStoreUserApprovalHandler.java index 7c543ab4..104a2ce3 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/TokenStoreUserApprovalHandler.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/TokenStoreUserApprovalHandler.java @@ -110,7 +110,7 @@ public class TokenStoreUserApprovalHandler implements UserApprovalHandler, Initi Set scopes = authorizationRequest.getScope(); if (clientDetailsService!=null) { try { - ClientDetails client = clientDetailsService.loadClientByClientId(clientId); + ClientDetails client = clientDetailsService.loadClientByClientId(clientId,true); approved = true; for (String scope : scopes) { if (!client.isAutoApprove(scope)) { diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/endpoint/OAuth20AccessConfirmationEndpoint.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/endpoint/OAuth20AccessConfirmationEndpoint.java index ff798155..595d90bb 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/endpoint/OAuth20AccessConfirmationEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/endpoint/OAuth20AccessConfirmationEndpoint.java @@ -83,7 +83,7 @@ public class OAuth20AccessConfirmationEndpoint { // Map model AuthorizationRequest clientAuth = (AuthorizationRequest) WebContext.getAttribute("authorizationRequest"); - ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId()); + ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId(),true); Apps app = (Apps)WebContext.getAttribute(WebConstants.AUTHORIZE_SIGN_ON_APP); WebContext.setAttribute(app.getId(), app.getIcon()); diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/endpoint/OAuth20UserApprovalHandler.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/endpoint/OAuth20UserApprovalHandler.java index bd5e272b..ba203681 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/endpoint/OAuth20UserApprovalHandler.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/endpoint/OAuth20UserApprovalHandler.java @@ -75,7 +75,7 @@ public class OAuth20UserApprovalHandler extends ApprovalStoreUserApprovalHandler Collection requestedScopes = authorizationRequest.getScope(); try { ClientDetails client = clientDetailsService - .loadClientByClientId(authorizationRequest.getClientId()); + .loadClientByClientId(authorizationRequest.getClientId(),true); for (String scope : requestedScopes) { if (client.isAutoApprove(scope) || client.isAutoApprove("all")) { approved = true; diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/client/ClientDetailsUserDetailsService.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/client/ClientDetailsUserDetailsService.java index 8aad9fa2..a25489a9 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/client/ClientDetailsUserDetailsService.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/client/ClientDetailsUserDetailsService.java @@ -45,7 +45,7 @@ public class ClientDetailsUserDetailsService implements UserDetailsService { public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { ClientDetails clientDetails; try { - clientDetails = clientDetailsService.loadClientByClientId(username); + clientDetails = clientDetailsService.loadClientByClientId(username,true); } catch (NoSuchClientException e) { throw new UsernameNotFoundException(e.getMessage(), e); } diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/client/JdbcClientDetailsService.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/client/JdbcClientDetailsService.java index 7672df6d..44d902d6 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/client/JdbcClientDetailsService.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/client/JdbcClientDetailsService.java @@ -69,9 +69,8 @@ public class JdbcClientDetailsService implements ClientDetailsService, ClientReg private static final String CLIENT_FIELDS_FOR_UPDATE = "RESOURCE_IDS, SCOPE, " + "AUTHORIZED_GRANT_TYPES, WEB_SERVER_REDIRECT_URI, AUTHORITIES, ACCESS_TOKEN_VALIDITY, " + "REFRESH_TOKEN_VALIDITY, ADDITIONAL_INFORMATION, AUTOAPPROVE, APPROVALPROMPT , " - + "IDTOKENSIGNINGALGORITHM, IDTOKENENCRYPTEDALGORITHM, IDTOKENENCRYPTIONMETHOD, " - + "USERINFOSIGNINGALGORITHM, USERINFOCRYPTEDALGORITHM, USERINFOENCRYPTIONMETHOD," - +" JWKSURI, PKCE, PROTOCOL , INSTID "; + + "ALGORITHM, ALGORITHMKEY, ENCRYPTIONMETHOD, SIGNATURE, SIGNATUREKEY, SUBJECT, " + + "USERINFORESPONSE, ISSUER, AUDIENCE, PKCE, PROTOCOL , INSTID "; private static final String CLIENT_FIELDS = "client_secret, " + CLIENT_FIELDS_FOR_UPDATE; @@ -83,7 +82,7 @@ public class JdbcClientDetailsService implements ClientDetailsService, ClientReg private static final String DEFAULT_SELECT_STATEMENT = BASE_FIND_STATEMENT + " where client_id = ?"; private static final String DEFAULT_INSERT_STATEMENT = "insert into mxk_apps_oauth_client_details (" + CLIENT_FIELDS - + ", client_id) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + + ", client_id) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; private static final String DEFAULT_UPDATE_STATEMENT = "update mxk_apps_oauth_client_details " + "set " + CLIENT_FIELDS_FOR_UPDATE.replaceAll(", ", "=?, ") + "=? where client_id = ?"; @@ -126,13 +125,18 @@ public class JdbcClientDetailsService implements ClientDetailsService, ClientReg this.passwordEncoder = passwordEncoder; } - public ClientDetails loadClientByClientId(String clientId) { + public ClientDetails loadClientByClientId(String clientId,boolean cached) { // cache in memory - ClientDetails details = clientDetailsCache.getIfPresent(clientId); + ClientDetails details = null; + if(cached) { + details = clientDetailsCache.getIfPresent(clientId); + } if(details == null) { try { details = jdbcTemplate.queryForObject(selectClientDetailsSql, new ClientDetailsRowMapper(), clientId); - clientDetailsCache.put(clientId, details); + if(cached) { + clientDetailsCache.put(clientId, details); + } } catch (EmptyResultDataAccessException e) { throw new NoSuchClientException("No client with requested id: " + clientId); } @@ -208,10 +212,11 @@ public class JdbcClientDetailsService implements ClientDetailsService, ClientReg : null, clientDetails.getAccessTokenValiditySeconds(), clientDetails.getRefreshTokenValiditySeconds(), json, getAutoApproveScopes(clientDetails),clientDetails.getApprovalPrompt(), - clientDetails.getIdTokenSigningAlgorithm(), - clientDetails.getIdTokenEncryptedAlgorithm(), clientDetails.getIdTokenEncryptionMethod(), - clientDetails.getUserInfoSigningAlgorithm(), clientDetails.getUserInfoEncryptedAlgorithm(), - clientDetails.getUserInfoEncryptionMethod(), clientDetails.getJwksUri(), + clientDetails.getAlgorithm(), + clientDetails.getAlgorithmKey(), clientDetails.getEncryptionMethod(), + clientDetails.getSignature(), clientDetails.getSignatureKey(), + clientDetails.getSubject(),clientDetails.getUserInfoResponse(), + clientDetails.getIssuer(), clientDetails.getAudience(), clientDetails.getPkce(), clientDetails.getProtocol(),clientDetails.getInstId(), clientDetails.getClientId() @@ -290,14 +295,16 @@ public class JdbcClientDetailsService implements ClientDetailsService, ClientReg details.setRefreshTokenValiditySeconds(rs.getInt(9)); } - details.setIdTokenEncryptedAlgorithm(rs.getString("IDTOKENENCRYPTEDALGORITHM")); - details.setIdTokenEncryptionMethod(rs.getString("IDTOKENENCRYPTIONMETHOD")); - details.setIdTokenSigningAlgorithm(rs.getString("IDTOKENSIGNINGALGORITHM")); + details.setAlgorithm(rs.getString("algorithm")); + details.setAlgorithmKey(rs.getString("algorithmKey")); + details.setEncryptionMethod(rs.getString("encryptionMethod")); - details.setUserInfoEncryptedAlgorithm(rs.getString("USERINFOCRYPTEDALGORITHM")); - details.setUserInfoEncryptionMethod(rs.getString("USERINFOENCRYPTIONMETHOD")); - details.setUserInfoSigningAlgorithm(rs.getString("USERINFOSIGNINGALGORITHM")); - details.setJwksUri(rs.getString("JWKSURI")); + details.setSignature(rs.getString("signature")); + details.setSignatureKey(rs.getString("signatureKey")); + details.setSubject(rs.getString("subject")); + details.setUserInfoResponse(rs.getString("userInfoResponse")); + details.setAudience(rs.getString("audience")); + details.setIssuer(rs.getString("issuer")); details.setApprovalPrompt(rs.getString("APPROVALPROMPT")); details.setPkce(rs.getString("PKCE")); details.setProtocol(rs.getString("PROTOCOL")); diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/AuthorizationEndpoint.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/AuthorizationEndpoint.java index 5ce1cee5..6569c526 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/AuthorizationEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/AuthorizationEndpoint.java @@ -117,7 +117,7 @@ public class AuthorizationEndpoint extends AbstractEndpoint { HttpServletRequest request, HttpServletResponse response, @PathVariable("id") String id){ - ClientDetails clientDetails =getClientDetailsService().loadClientByClientId(id); + ClientDetails clientDetails =getClientDetailsService().loadClientByClientId(id,true); _logger.debug(""+clientDetails); String authorizationUrl = ""; try { @@ -169,7 +169,7 @@ public class AuthorizationEndpoint extends AbstractEndpoint { "User must be authenticated with Spring Security before authorization can be completed."); } - ClientDetails client = getClientDetailsService().loadClientByClientId(authorizationRequest.getClientId()); + ClientDetails client = getClientDetailsService().loadClientByClientId(authorizationRequest.getClientId(),true); // The resolved redirect URI is either the redirect_uri from the parameters or the one from // clientDetails. Either way we need to store it on the AuthorizationRequest. diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpoint.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpoint.java index 492534ec..bb291743 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpoint.java @@ -122,7 +122,7 @@ public class TokenEndpoint extends AbstractEndpoint { } String clientId = getClientId((Authentication)principal); - ClientDetails authenticatedClient = getClientDetailsService().loadClientByClientId(clientId); + ClientDetails authenticatedClient = getClientDetailsService().loadClientByClientId(clientId,true); TokenRequest tokenRequest = getOAuth2RequestFactory().createTokenRequest(parameters, authenticatedClient); diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/request/DefaultOAuth2RequestFactory.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/request/DefaultOAuth2RequestFactory.java index 94c542f3..d5115296 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/request/DefaultOAuth2RequestFactory.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/request/DefaultOAuth2RequestFactory.java @@ -85,7 +85,7 @@ public class DefaultOAuth2RequestFactory implements OAuth2RequestFactory { Collections. emptyMap(), clientId, scopes, null, null, false, state, redirectUri, responseTypes,codeChallenge,codeChallengeMethod); - ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId); + ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId,true); request.setResourceIdsAndAuthoritiesFromClientDetails(clientDetails); return request; @@ -133,7 +133,7 @@ public class DefaultOAuth2RequestFactory implements OAuth2RequestFactory { private Set extractScopes(Map requestParameters, String clientId) { Set scopes = OAuth2Utils.parseParameterList(requestParameters.get(OAuth2Constants.PARAMETER.SCOPE)); - ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId); + ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId,true); if ((scopes == null || scopes.isEmpty())) { // If no scopes are specified in the incoming data, use the default values registered with the client diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/token/AbstractTokenGranter.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/token/AbstractTokenGranter.java index 6b58c5e9..225659a8 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/token/AbstractTokenGranter.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/token/AbstractTokenGranter.java @@ -57,7 +57,7 @@ public abstract class AbstractTokenGranter implements TokenGranter { } String clientId = tokenRequest.getClientId(); - ClientDetails client = clientDetailsService.loadClientByClientId(clientId); + ClientDetails client = clientDetailsService.loadClientByClientId(clientId,true); validateGrantType(grantType, client); logger.debug("Getting access token for: " + clientId); diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/token/DefaultTokenServices.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/token/DefaultTokenServices.java index 2fe7a1db..80a76f9f 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/token/DefaultTokenServices.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/token/DefaultTokenServices.java @@ -244,7 +244,7 @@ public class DefaultTokenServices implements AuthorizationServerTokenServices, R if (clientDetailsService != null) { String clientId = result.getOAuth2Request().getClientId(); try { - clientDetailsService.loadClientByClientId(clientId); + clientDetailsService.loadClientByClientId(clientId,true); } catch (ClientRegistrationException e) { throw new InvalidTokenException("Client not valid: " + clientId, e); @@ -310,7 +310,7 @@ public class DefaultTokenServices implements AuthorizationServerTokenServices, R */ protected int getAccessTokenValiditySeconds(OAuth2Request clientAuth) { if (clientDetailsService != null) { - ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId()); + ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId(),true); Integer validity = client.getAccessTokenValiditySeconds(); if (validity != null) { return validity; @@ -327,7 +327,7 @@ public class DefaultTokenServices implements AuthorizationServerTokenServices, R */ protected int getRefreshTokenValiditySeconds(OAuth2Request clientAuth) { if (clientDetailsService != null) { - ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId()); + ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId(),true); Integer validity = client.getRefreshTokenValiditySeconds(); if (validity != null) { return validity; @@ -345,7 +345,7 @@ public class DefaultTokenServices implements AuthorizationServerTokenServices, R */ protected boolean isSupportRefreshToken(OAuth2Request clientAuth) { if (clientDetailsService != null) { - ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId()); + ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId(),true); return client.getAuthorizedGrantTypes().contains("refresh_token"); } return this.supportRefreshToken; diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/OAuthDefaultUserInfoAdapter.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/OAuthDefaultUserInfoAdapter.java index 34f1f1f5..f9033974 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/OAuthDefaultUserInfoAdapter.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/OAuthDefaultUserInfoAdapter.java @@ -19,24 +19,41 @@ package org.maxkey.authz.oauth2.provider.userinfo.endpoint; import java.util.HashMap; -import org.maxkey.authn.SigninPrincipal; import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; -import org.maxkey.entity.UserInfo; +import org.maxkey.entity.apps.oauth2.provider.ClientDetails; import org.maxkey.util.JsonUtils; import org.maxkey.util.StringGenerator; import org.maxkey.web.WebConstants; -import org.springframework.web.servlet.ModelAndView; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class OAuthDefaultUserInfoAdapter extends AbstractAuthorizeAdapter { + final static Logger _logger = LoggerFactory.getLogger(OAuthDefaultUserInfoAdapter.class); + ClientDetails clientDetails; + + public OAuthDefaultUserInfoAdapter() {} + + public OAuthDefaultUserInfoAdapter(ClientDetails clientDetails) { + this.clientDetails = clientDetails; + } @Override - public String generateInfo(SigninPrincipal authentication,UserInfo userInfo,Object app) { + public Object generateInfo() { + String subject = AbstractAuthorizeAdapter.getValueByUserAttr(userInfo, clientDetails.getSubject()); + _logger.debug("userId : {} , username : {} , displayName : {} , subject : {}" , + userInfo.getId(), + userInfo.getUsername(), + userInfo.getDisplayName(), + subject); + HashMap beanMap = new HashMap(); beanMap.put("randomId",(new StringGenerator()).uuidGenerate()); beanMap.put("userId", userInfo.getId()); //for spring security oauth2 - beanMap.put("user", userInfo.getUsername()); - beanMap.put("username", userInfo.getUsername()); + beanMap.put("user", subject); + beanMap.put("username", subject); + + beanMap.put("displayName", userInfo.getDisplayName()); beanMap.put("employeeNumber", userInfo.getEmployeeNumber()); beanMap.put("email", userInfo.getEmail()); beanMap.put("mobile", userInfo.getMobile()); @@ -56,15 +73,11 @@ public class OAuthDefaultUserInfoAdapter extends AbstractAuthorizeAdapter { return info; } - @Override - public String encrypt(String data, String algorithmKey, String algorithm) { - return null; + public ClientDetails getClientDetails() { + return clientDetails; } - @Override - public ModelAndView authorize(UserInfo userInfo, Object app, String data,ModelAndView modelAndView) { - - return null; + public void setClientDetails(ClientDetails clientDetails) { + this.clientDetails = clientDetails; } - } diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/UserInfoEndpoint.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/UserInfoEndpoint.java index fc078da2..6bf24cf9 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/UserInfoEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/UserInfoEndpoint.java @@ -17,10 +17,14 @@ package org.maxkey.authz.oauth2.provider.userinfo.endpoint; +import java.lang.reflect.InvocationTargetException; import java.util.Enumeration; import java.util.HashMap; + import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.beanutils.BeanUtils; import org.maxkey.authn.SigninPrincipal; import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; import org.maxkey.authz.oauth2.common.OAuth2Constants; @@ -29,12 +33,9 @@ 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.ConstsBoolean; -import org.maxkey.crypto.jwt.encryption.service.JwtEncryptionAndDecryptionService; -import org.maxkey.crypto.jwt.encryption.service.impl.RecipientJwtEncryptionAndDecryptionServiceBuilder; -import org.maxkey.crypto.jwt.signer.service.JwtSigningAndValidationService; -import org.maxkey.crypto.jwt.signer.service.impl.SymmetricSigningAndValidationServiceBuilder; import org.maxkey.entity.UserInfo; import org.maxkey.entity.apps.Apps; +import org.maxkey.entity.apps.oauth2.provider.ClientDetails; import org.maxkey.persistence.service.AppsService; import org.maxkey.persistence.service.UserInfoService; import org.maxkey.util.AuthorizationHeaderUtils; @@ -51,6 +52,7 @@ import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; + import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -66,7 +68,6 @@ public class UserInfoEndpoint { @Qualifier("oauth20TokenServices") private DefaultTokenServices oauth20tokenServices; - @Autowired @Qualifier("userInfoService") private UserInfoService userInfoService; @@ -74,25 +75,7 @@ public class UserInfoEndpoint { @Autowired @Qualifier("appsService") protected AppsService appsService; - - @Autowired - @Qualifier("jwtSignerValidationService") - private JwtSigningAndValidationService jwtSignerValidationService; - - @Autowired - @Qualifier("jwtEncryptionService") - private JwtEncryptionAndDecryptionService jwtEnDecryptionService; - - - - private SymmetricSigningAndValidationServiceBuilder symmetricJwtSignerServiceBuilder - =new SymmetricSigningAndValidationServiceBuilder(); - private RecipientJwtEncryptionAndDecryptionServiceBuilder recipientJwtEnDecryptionServiceBuilder - =new RecipientJwtEncryptionAndDecryptionServiceBuilder(); - - OAuthDefaultUserInfoAdapter defaultOAuthUserInfoAdapter=new OAuthDefaultUserInfoAdapter(); - @Autowired protected HttpResponseAdapter httpResponseAdapter; @@ -128,20 +111,29 @@ public class UserInfoEndpoint { principal=((SigninPrincipal)oAuth2Authentication.getUserAuthentication().getPrincipal()).getUsername(); String client_id= oAuth2Authentication.getOAuth2Request().getClientId(); + ClientDetails clientDetails = + clientDetailsService.loadClientByClientId(client_id,true); + UserInfo userInfo=queryUserInfo(principal); - Apps app=appsService.get(client_id); + Apps app = appsService.get(client_id); AbstractAuthorizeAdapter adapter; if(ConstsBoolean.isTrue(app.getIsAdapter())){ adapter =(AbstractAuthorizeAdapter)Instance.newInstance(app.getAdapter()); + try { + BeanUtils.setProperty(adapter, "clientDetails", clientDetails); + } catch (IllegalAccessException | InvocationTargetException e) { + _logger.error("setProperty error . ", e); + } }else{ - adapter =(AbstractAuthorizeAdapter)defaultOAuthUserInfoAdapter; + adapter =(AbstractAuthorizeAdapter)new OAuthDefaultUserInfoAdapter(clientDetails); } + adapter.setAuthentication((SigninPrincipal)oAuth2Authentication.getUserAuthentication().getPrincipal()); + adapter.setUserInfo(userInfo); + adapter.setApp(app); - String jsonData=adapter.generateInfo( - (SigninPrincipal)oAuth2Authentication.getUserAuthentication().getPrincipal(), - userInfo, app); - httpResponseAdapter.write(response,jsonData,"json"); + Object jsonData = adapter.generateInfo(); + httpResponseAdapter.write(response,jsonData.toString(),"json"); }catch(OAuth2Exception e){ HashMapauthzException=new HashMap(); authzException.put(OAuth2Exception.ERROR, e.getOAuth2ErrorCode()); @@ -175,15 +167,4 @@ public class UserInfoEndpoint { this.userInfoService = userInfoService; } -// -// -// public void setJwtSignerValidationService( -// JwtSigningAndValidationService jwtSignerValidationService) { -// this.jwtSignerValidationService = jwtSignerValidationService; -// } -// -// public void setJwtEnDecryptionService( -// JwtEncryptionAndDecryptionService jwtEnDecryptionService) { -// this.jwtEnDecryptionService = jwtEnDecryptionService; -// } } diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/OpenIdConnectUserInfoEndpoint.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/UserInfoOIDCEndpoint.java similarity index 59% rename from maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/OpenIdConnectUserInfoEndpoint.java rename to maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/UserInfoOIDCEndpoint.java index 3e4f0a3a..bf22ffe9 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/OpenIdConnectUserInfoEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/UserInfoOIDCEndpoint.java @@ -17,6 +17,8 @@ package org.maxkey.authz.oauth2.provider.userinfo.endpoint; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; import java.util.Arrays; import java.util.Date; import java.util.HashMap; @@ -24,18 +26,19 @@ import java.util.Set; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; import org.maxkey.authn.SigninPrincipal; +import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; import org.maxkey.authz.oauth2.common.OAuth2Constants; 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.ContentType; -import org.maxkey.crypto.jwt.encryption.service.JwtEncryptionAndDecryptionService; -import org.maxkey.crypto.jwt.encryption.service.impl.RecipientJwtEncryptionAndDecryptionServiceBuilder; -import org.maxkey.crypto.jwt.signer.service.JwtSigningAndValidationService; -import org.maxkey.crypto.jwt.signer.service.impl.SymmetricSigningAndValidationServiceBuilder; -import org.maxkey.crypto.password.PasswordReciprocal; +import org.maxkey.crypto.jose.keystore.JWKSetKeyStore; +import org.maxkey.crypto.jwt.encryption.service.impl.DefaultJwtEncryptionAndDecryptionService; +import org.maxkey.crypto.jwt.signer.service.impl.DefaultJwtSigningAndValidationService; import org.maxkey.entity.UserInfo; import org.maxkey.entity.apps.oauth2.provider.ClientDetails; import org.maxkey.persistence.service.AppsService; @@ -54,14 +57,18 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import com.nimbusds.jose.EncryptionMethod; +import com.nimbusds.jose.JOSEException; import com.nimbusds.jose.JWEAlgorithm; import com.nimbusds.jose.JWEHeader; +import com.nimbusds.jose.JWEObject; import com.nimbusds.jose.JWSAlgorithm; import com.nimbusds.jose.JWSHeader; -import com.nimbusds.jwt.EncryptedJWT; +import com.nimbusds.jose.Payload; import com.nimbusds.jwt.JWT; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.JWTClaimsSet.Builder; +import com.nimbusds.jwt.PlainJWT; + import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -69,8 +76,8 @@ import com.nimbusds.jwt.SignedJWT; @Tag(name = "2-1-OAuth v2.0 API文档模块") @Controller -public class OpenIdConnectUserInfoEndpoint { - final static Logger _logger = LoggerFactory.getLogger(OpenIdConnectUserInfoEndpoint.class); +public class UserInfoOIDCEndpoint { + final static Logger _logger = LoggerFactory.getLogger(UserInfoOIDCEndpoint.class); @Autowired @Qualifier("oauth20JdbcClientDetailsService") private ClientDetailsService clientDetailsService; @@ -88,22 +95,6 @@ public class OpenIdConnectUserInfoEndpoint { @Qualifier("appsService") protected AppsService appsService; - @Autowired - @Qualifier("jwtSignerValidationService") - private JwtSigningAndValidationService jwtSignerValidationService; - - @Autowired - @Qualifier("jwtEncryptionService") - private JwtEncryptionAndDecryptionService jwtEnDecryptionService; - - - - private SymmetricSigningAndValidationServiceBuilder symmetricJwtSignerServiceBuilder - =new SymmetricSigningAndValidationServiceBuilder(); - - private RecipientJwtEncryptionAndDecryptionServiceBuilder recipientJwtEnDecryptionServiceBuilder - =new RecipientJwtEncryptionAndDecryptionServiceBuilder(); - OAuthDefaultUserInfoAdapter defaultOAuthUserInfoAdapter=new OAuthDefaultUserInfoAdapter(); @Autowired @@ -127,23 +118,31 @@ public class OpenIdConnectUserInfoEndpoint { principal=((SigninPrincipal)oAuth2Authentication.getPrincipal()).getUsername(); - Setscopes=oAuth2Authentication.getOAuth2Request().getScope(); - ClientDetails clientDetails = clientDetailsService.loadClientByClientId(oAuth2Authentication.getOAuth2Request().getClientId()); + Setscopes = oAuth2Authentication.getOAuth2Request().getScope(); + ClientDetails clientDetails = + clientDetailsService.loadClientByClientId(oAuth2Authentication.getOAuth2Request().getClientId(),true); - UserInfo userInfo=queryUserInfo(principal); - String userJson=""; + UserInfo userInfo = queryUserInfo(principal); + String userJson = ""; Builder jwtClaimsSetBuilder= new JWTClaimsSet.Builder(); SigninPrincipal authentication = (SigninPrincipal)oAuth2Authentication.getUserAuthentication().getPrincipal(); - jwtClaimsSetBuilder.claim("sub", userInfo.getId()); + String subject = AbstractAuthorizeAdapter.getValueByUserAttr(userInfo, clientDetails.getSubject()); + _logger.debug("userId : {} , username : {} , displayName : {} , subject : {}" , + userInfo.getId(), + userInfo.getUsername(), + userInfo.getDisplayName(), + subject); + + jwtClaimsSetBuilder.claim("sub", subject); jwtClaimsSetBuilder.claim("institution", userInfo.getInstId()); jwtClaimsSetBuilder.claim(WebConstants.ONLINE_TICKET_NAME, authentication.getOnlineTicket().getTicketId()); if(scopes.contains("profile")){ jwtClaimsSetBuilder.claim("userId", userInfo.getId()); jwtClaimsSetBuilder.claim("user", userInfo.getUsername()); - jwtClaimsSetBuilder.claim("name", userInfo.getUsername()); + jwtClaimsSetBuilder.claim("name", userInfo.getDisplayName()); jwtClaimsSetBuilder.claim("preferred_username", userInfo.getDisplayName()); jwtClaimsSetBuilder.claim("given_name", userInfo.getGivenName()); jwtClaimsSetBuilder.claim("family_name", userInfo.getFamilyName()); @@ -151,7 +150,8 @@ public class OpenIdConnectUserInfoEndpoint { jwtClaimsSetBuilder.claim("nickname", userInfo.getNickName()); jwtClaimsSetBuilder.claim("profile", "profile"); jwtClaimsSetBuilder.claim("picture", "picture"); - jwtClaimsSetBuilder.claim("website", userInfo.getWebSite()); + //jwtClaimsSetBuilder.claim("website", userInfo.getWebSite()); + jwtClaimsSetBuilder.claim("displayName", userInfo.getDisplayName()); jwtClaimsSetBuilder.claim("departmentId", userInfo.getDepartmentId()); jwtClaimsSetBuilder.claim("department", userInfo.getDepartment()); @@ -198,69 +198,88 @@ public class OpenIdConnectUserInfoEndpoint { .jwtID(UUID.randomUUID().toString())// set a random NONCE in the middle of it .audience(Arrays.asList(clientDetails.getClientId())) .issueTime(new Date()) - .expirationTime(new Date(new Date().getTime()+clientDetails.getAccessTokenValiditySeconds()*1000)); + .expirationTime(new Date(new Date().getTime() + clientDetails.getAccessTokenValiditySeconds() * 1000)); + + //default ContentType + response.setContentType(ContentType.APPLICATION_JWT_UTF8); 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") - &&clientDetails.getJwksUri()!=null&&clientDetails.getJwksUri().length()>4 - ) { - //需要加密 - response.setContentType(ContentType.APPLICATION_JWT_UTF8); - JwtEncryptionAndDecryptionService recipientJwtEnDecryptionService = - recipientJwtEnDecryptionServiceBuilder.serviceBuilder(clientDetails.getJwksUri()); - - if (recipientJwtEnDecryptionService != null) { - JWEAlgorithm jweAlgorithm=new JWEAlgorithm(clientDetails.getUserInfoEncryptedAlgorithm()); - EncryptionMethod encryptionMethod=new EncryptionMethod(clientDetails.getUserInfoEncryptionMethod()); - EncryptedJWT encryptedJWT = new EncryptedJWT(new JWEHeader(jweAlgorithm, encryptionMethod), userInfoJWTClaims); - recipientJwtEnDecryptionService.encryptJwt(encryptedJWT); - userJson=encryptedJWT.serialize(); - }else{ - _logger.error("Couldn't find encrypter for client: " + clientDetails.getClientId()); - HashMapauthzException=new HashMap(); - authzException.put(OAuth2Exception.ERROR, "error"); - 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")) { - //需要签名 - 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=PasswordReciprocal.getInstance().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(); - userInfoJWT = new SignedJWT(new JWSHeader(signingAlg), userInfoJWTClaims); - // sign it with the server's key - jwtSignerValidationService.signJwt((SignedJWT) userInfoJWT); + + if(clientDetails.getUserInfoResponse().equalsIgnoreCase("NORMAL")) { + response.setContentType(ContentType.APPLICATION_JSON_UTF8); + userJson = userInfoJWTClaims.toString(); + }else if (StringUtils.isNotBlank(clientDetails.getSignature()) + && !clientDetails.getSignature().equalsIgnoreCase("none") + && clientDetails.getUserInfoResponse().equalsIgnoreCase("ENCRYPTION")) { + //需要签名 signed ID token + JWKSetKeyStore jwkSetKeyStore = new JWKSetKeyStore("{\"keys\": ["+clientDetails.getSignatureKey()+"]}"); + DefaultJwtSigningAndValidationService jwtSignerService = null; + try { + jwtSignerService = new DefaultJwtSigningAndValidationService(jwkSetKeyStore); + }catch(Exception e) { + _logger.error("Couldn't create Jwt Signing Service",e); + } + + jwtSignerService.setDefaultSignerKeyId(clientDetails.getClientId() + "_sig"); + jwtSignerService.setDefaultSigningAlgorithmName(clientDetails.getSignature()); + + JWSAlgorithm signingAlg = jwtSignerService.getDefaultSigningAlgorithm(); + _logger.trace(" signingAlg {}" , signingAlg); + userInfoJWTClaims = new JWTClaimsSet + .Builder(userInfoJWTClaims) + .claim("kid", jwtSignerService.getDefaultSignerKeyId()) + .build(); + + userInfoJWT = new SignedJWT(new JWSHeader(signingAlg), userInfoJWTClaims); + // sign it with the server's key + jwtSignerService.signJwt((SignedJWT) userInfoJWT); + + userJson = userInfoJWT.serialize(); + }else if (StringUtils.isNotBlank(clientDetails.getAlgorithm()) + && !clientDetails.getAlgorithm().equalsIgnoreCase("none") + && clientDetails.getUserInfoResponse().equalsIgnoreCase("SIGNING") + ) { + //TODO: 需要加密 + JWKSetKeyStore jwkSetKeyStore_Enc = new JWKSetKeyStore("{\"keys\": ["+clientDetails.getAlgorithmKey()+"]}"); + try { + DefaultJwtEncryptionAndDecryptionService jwtEncryptionService = + new DefaultJwtEncryptionAndDecryptionService(jwkSetKeyStore_Enc); + jwtEncryptionService.setDefaultEncryptionKeyId(clientDetails.getClientId() + "_enc"); + jwtEncryptionService.setDefaultAlgorithm(clientDetails.getAlgorithm()); + JWEAlgorithm encryptAlgorithm = null; + if(clientDetails.getAlgorithm().startsWith("RSA")) { + encryptAlgorithm = jwtEncryptionService.getDefaultAlgorithm(); + }else { + encryptAlgorithm = JWEAlgorithm.DIR; + } + _logger.trace(" encryptAlgorithm {}" , encryptAlgorithm); + EncryptionMethod encryptionMethod = + jwtEncryptionService.parseEncryptionMethod(clientDetails.getEncryptionMethod()); + + Payload payload = userInfoJWTClaims.toPayload(); + + // Example Request JWT encrypted with RSA-OAEP-256 and 128-bit AES/GCM + //JWEHeader jweHeader = new JWEHeader(JWEAlgorithm.RSA1_5, EncryptionMethod.A128GCM); + + JWEObject jweObject = new JWEObject( + new JWEHeader.Builder(new JWEHeader(encryptAlgorithm,encryptionMethod)) + .contentType("JWT") // required to indicate nested JWT + .build(), + payload); + + jwtEncryptionService.encryptJwt(jweObject); + userJson = jweObject.serialize(); + } catch (NoSuchAlgorithmException | InvalidKeySpecException | JOSEException e) { + _logger.error("Couldn't create Jwt Encryption Exception", e); } - userJson=userInfoJWT.serialize(); }else { - //不需要加密和签名 - response.setContentType(ContentType.APPLICATION_JSON_UTF8); - // unsigned ID token - //userInfoJWT = new PlainJWT(userInfoJWTClaims); - userJson=JsonUtils.gson2Json(jwtClaimsSetBuilder.getClaims()); + //不需要加密和签名 unsigned ID token + userInfoJWT = new PlainJWT(userInfoJWTClaims); + userJson = userInfoJWT.serialize(); } - + + _logger.trace("OpenID Connect Response {}",userJson); return userJson; }catch(OAuth2Exception e){ @@ -280,9 +299,7 @@ public class OpenIdConnectUserInfoEndpoint { } public UserInfo queryUserInfo(String userId){ - _logger.debug("userId : "+userId); - UserInfo userInfo = (UserInfo) userInfoService.findByUsername(userId); - return userInfo; + return (UserInfo) userInfoService.findByUsername(userId); } @@ -295,16 +312,4 @@ public class OpenIdConnectUserInfoEndpoint { public void setUserInfoService(UserInfoService userInfoService) { this.userInfoService = userInfoService; } - -// -// -// public void setJwtSignerValidationService( -// JwtSigningAndValidationService jwtSignerValidationService) { -// this.jwtSignerValidationService = jwtSignerValidationService; -// } -// -// public void setJwtEnDecryptionService( -// JwtEncryptionAndDecryptionService jwtEnDecryptionService) { -// this.jwtEnDecryptionService = jwtEnDecryptionService; -// } } diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oidc/idtoken/OIDCIdTokenEnhancer.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oidc/idtoken/OIDCIdTokenEnhancer.java index 8557b235..33473547 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oidc/idtoken/OIDCIdTokenEnhancer.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oidc/idtoken/OIDCIdTokenEnhancer.java @@ -20,11 +20,14 @@ */ package org.maxkey.authz.oidc.idtoken; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; import java.util.Arrays; import java.util.Date; import java.util.Set; import java.util.UUID; +import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat; import org.maxkey.authz.oauth2.common.DefaultOAuth2AccessToken; @@ -34,11 +37,9 @@ import org.maxkey.authz.oauth2.provider.OAuth2Authentication; import org.maxkey.authz.oauth2.provider.OAuth2Request; import org.maxkey.authz.oauth2.provider.token.TokenEnhancer; import org.maxkey.configuration.oidc.OIDCProviderMetadata; -import org.maxkey.crypto.jwt.encryption.service.JwtEncryptionAndDecryptionService; -import org.maxkey.crypto.jwt.encryption.service.impl.RecipientJwtEncryptionAndDecryptionServiceBuilder; -import org.maxkey.crypto.jwt.signer.service.JwtSigningAndValidationService; -import org.maxkey.crypto.jwt.signer.service.impl.SymmetricSigningAndValidationServiceBuilder; -import org.maxkey.crypto.password.PasswordReciprocal; +import org.maxkey.crypto.jose.keystore.JWKSetKeyStore; +import org.maxkey.crypto.jwt.encryption.service.impl.DefaultJwtEncryptionAndDecryptionService; +import org.maxkey.crypto.jwt.signer.service.impl.DefaultJwtSigningAndValidationService; import org.maxkey.entity.apps.oauth2.provider.ClientDetails; import org.maxkey.web.WebContext; @@ -47,16 +48,16 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Strings; -import com.nimbusds.jose.Algorithm; import com.nimbusds.jose.EncryptionMethod; +import com.nimbusds.jose.JOSEException; import com.nimbusds.jose.JWEAlgorithm; import com.nimbusds.jose.JWEHeader; +import com.nimbusds.jose.JWEObject; import com.nimbusds.jose.JWSAlgorithm; import com.nimbusds.jose.JWSHeader; -import com.nimbusds.jwt.EncryptedJWT; +import com.nimbusds.jose.Payload; import com.nimbusds.jwt.JWT; import com.nimbusds.jwt.JWTClaimsSet; -import com.nimbusds.jwt.PlainJWT; import com.nimbusds.jwt.SignedJWT; /** @@ -64,37 +65,20 @@ import com.nimbusds.jwt.SignedJWT; * */ public class OIDCIdTokenEnhancer implements TokenEnhancer { - private final static Logger logger = LoggerFactory.getLogger(OIDCIdTokenEnhancer.class); + private final static Logger _logger = LoggerFactory.getLogger(OIDCIdTokenEnhancer.class); public final static String ID_TOKEN_SCOPE="openid"; private OIDCProviderMetadata providerMetadata; - private JwtSigningAndValidationService jwtSignerService; - - private JwtEncryptionAndDecryptionService jwtEnDecryptionService; + private ClientDetailsService clientDetailsService; - - private SymmetricSigningAndValidationServiceBuilder symmetricJwtSignerServiceBuilder - =new SymmetricSigningAndValidationServiceBuilder(); - - private RecipientJwtEncryptionAndDecryptionServiceBuilder recipientJwtEnDecryptionServiceBuilder - =new RecipientJwtEncryptionAndDecryptionServiceBuilder(); - + public void setProviderMetadata(OIDCProviderMetadata providerMetadata) { this.providerMetadata = providerMetadata; } - public void setJwtSignerService(JwtSigningAndValidationService jwtSignerService) { - this.jwtSignerService = jwtSignerService; - } - - public void setJwtEnDecryptionService( - JwtEncryptionAndDecryptionService jwtEnDecryptionService) { - this.jwtEnDecryptionService = jwtEnDecryptionService; - } - public void setClientDetailsService(ClientDetailsService clientDetailsService) { this.clientDetailsService = clientDetailsService; } @@ -103,12 +87,28 @@ public class OIDCIdTokenEnhancer implements TokenEnhancer { public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { OAuth2Request request=authentication.getOAuth2Request(); if (request.getScope().contains(ID_TOKEN_SCOPE)) {//Enhance for OpenID Connect - ClientDetails clientDetails = clientDetailsService.loadClientByClientId(authentication.getOAuth2Request().getClientId()); + ClientDetails clientDetails = + clientDetailsService.loadClientByClientId(authentication.getOAuth2Request().getClientId(),true); + + DefaultJwtSigningAndValidationService jwtSignerService = null; + JWSAlgorithm signingAlg = null; + try {//jwtSignerService + if (StringUtils.isNotBlank(clientDetails.getSignature()) && !clientDetails.getSignature().equalsIgnoreCase("none")) { + JWKSetKeyStore jwkSetKeyStore = new JWKSetKeyStore("{\"keys\": ["+clientDetails.getSignatureKey()+"]}"); + jwtSignerService = new DefaultJwtSigningAndValidationService(jwkSetKeyStore); + jwtSignerService.setDefaultSignerKeyId(clientDetails.getClientId() + "_sig"); + jwtSignerService.setDefaultSigningAlgorithmName(clientDetails.getSignature()); + signingAlg = jwtSignerService.getDefaultSigningAlgorithm(); + _logger.trace(" signingAlg {}" , signingAlg); + } + }catch(Exception e) { + _logger.error("Couldn't create Jwt Signing Service",e); + } JWTClaimsSet.Builder builder=new JWTClaimsSet.Builder(); builder.subject(authentication.getName()) .expirationTime(accessToken.getExpiration()) - .claim(providerMetadata.getIssuer(), true) + .issuer(clientDetails.getIssuer()) .issueTime(new Date()) .audience(Arrays.asList(authentication.getOAuth2Request().getClientId())) .jwtID(UUID.randomUUID().toString()); @@ -118,8 +118,7 @@ public class OIDCIdTokenEnhancer implements TokenEnhancer { * @see http://openid.net/specs/openid-connect-core-1_0.html#SelfIssuedDiscovery * 7. Self-Issued OpenID Provider */ - - if(providerMetadata.getIssuer().equalsIgnoreCase("https://self-issued.me")){ + if(providerMetadata.getIssuer().equalsIgnoreCase("https://self-issued.me") && jwtSignerService != null){ builder.claim("sub_jwk", jwtSignerService.getAllPublicKeys().get(jwtSignerService.getDefaultSignerKeyId())); } @@ -127,76 +126,79 @@ public class OIDCIdTokenEnhancer implements TokenEnhancer { if (request.getExtensions().containsKey("max_age") || (request.getExtensions().containsKey("idtoken")) // parse the ID Token claims (#473) -- for now assume it could be in there ) { - DateTime loginDate=DateTime.parse(WebContext.getUserInfo().getLastLoginTime(), DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")); - builder.claim("auth_time", loginDate.getMillis()/ 1000); + DateTime loginDate = DateTime.parse(WebContext.getUserInfo().getLastLoginTime(), DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")); + builder.claim("auth_time", loginDate.getMillis()/1000); } String nonce = (String)request.getExtensions().get("nonce"); if (!Strings.isNullOrEmpty(nonce)) { builder.claim("nonce", nonce); } - - JWSAlgorithm signingAlg = jwtSignerService.getDefaultSigningAlgorithm(); - SignedJWT signed = new SignedJWT(new JWSHeader(signingAlg), builder.build()); - Set responseTypes = request.getResponseTypes(); - - if (responseTypes.contains("token")) { - // calculate the token hash - Base64URL at_hash = IdTokenHashUtils.getAccessTokenHash(signingAlg, signed); - builder.claim("at_hash", at_hash); - } - logger.debug("idClaims "+builder.build()); - - JWT idToken=null; - if (clientDetails.getIdTokenEncryptedAlgorithm() != null && !clientDetails.getIdTokenEncryptedAlgorithm().equals("none") - && clientDetails.getIdTokenEncryptionMethod() != null && !clientDetails.getIdTokenEncryptionMethod().equals("none") - &&clientDetails.getJwksUri()!=null&&clientDetails.getJwksUri().length()>4) { - - JwtEncryptionAndDecryptionService recipientJwtEnDecryptionService = - recipientJwtEnDecryptionServiceBuilder.serviceBuilder(clientDetails.getJwksUri()); - - if (recipientJwtEnDecryptionService != null) { - JWEAlgorithm jweAlgorithm=new JWEAlgorithm(clientDetails.getIdTokenEncryptedAlgorithm()); - EncryptionMethod encryptionMethod=new EncryptionMethod(clientDetails.getIdTokenEncryptionMethod()); - EncryptedJWT encryptedJWT = new EncryptedJWT(new JWEHeader(jweAlgorithm, encryptionMethod), builder.build()); - recipientJwtEnDecryptionService.encryptJwt(encryptedJWT); - idToken=encryptedJWT; - }else{ - logger.error("Couldn't create Jwt Encryption Service"); + if(jwtSignerService != null) { + SignedJWT signed = new SignedJWT(new JWSHeader(signingAlg), builder.build()); + Set responseTypes = request.getResponseTypes(); + + if (responseTypes.contains("token")) { + // calculate the token hash + Base64URL at_hash = IdTokenHashUtils.getAccessTokenHash(signingAlg, signed); + builder.claim("at_hash", at_hash); } - } else { - if (signingAlg==null||signingAlg.equals(Algorithm.NONE)) { - // unsigned ID token - idToken = new PlainJWT(builder.build()); - } else { + _logger.debug("idClaims {}",builder.build()); + } + String idTokenString = ""; + if (StringUtils.isNotBlank(clientDetails.getSignature()) + && !clientDetails.getSignature().equalsIgnoreCase("none")) { + try { + builder.claim("kid", jwtSignerService.getDefaultSignerKeyId()); // 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=PasswordReciprocal.getInstance().decoder(clientDetails.getClientSecret()); - - JwtSigningAndValidationService symmetricJwtSignerService =symmetricJwtSignerServiceBuilder.serviceBuilder(client_secret); - if(symmetricJwtSignerService!=null){ - builder.claim("kid", "SYMMETRIC-KEY"); - idToken = new SignedJWT(new JWSHeader(signingAlg), builder.build()); - symmetricJwtSignerService.signJwt((SignedJWT) idToken); - }else { - logger.error("Couldn't create symmetric validator for client " + clientDetails.getClientId() + " without a client secret"); - } - } else { - builder.claim("kid", jwtSignerService.getDefaultSignerKeyId()); - idToken = new SignedJWT(new JWSHeader(signingAlg), builder.build()); - // sign it with the server's key - jwtSignerService.signJwt((SignedJWT) idToken); - } + JWT idToken = new SignedJWT(new JWSHeader(signingAlg), builder.build()); + // sign it with the server's key + jwtSignerService.signJwt((SignedJWT) idToken); + idTokenString = idToken.serialize(); + _logger.debug("idToken {}",idTokenString); + }catch(Exception e) { + _logger.error("Couldn't create Jwt Signing Exception",e); } + }else if (StringUtils.isNotBlank(clientDetails.getAlgorithm()) + && !clientDetails.getAlgorithm().equalsIgnoreCase("none")) { + JWKSetKeyStore jwkSetKeyStore_Enc = new JWKSetKeyStore("{\"keys\": ["+clientDetails.getAlgorithmKey()+"]}"); + try { + DefaultJwtEncryptionAndDecryptionService jwtEncryptionService = + new DefaultJwtEncryptionAndDecryptionService(jwkSetKeyStore_Enc); + jwtEncryptionService.setDefaultEncryptionKeyId(clientDetails.getClientId() + "_enc"); + jwtEncryptionService.setDefaultAlgorithm(clientDetails.getAlgorithm()); + JWEAlgorithm encryptAlgorithm = null; + if(clientDetails.getAlgorithm().startsWith("RSA")) { + encryptAlgorithm = jwtEncryptionService.getDefaultAlgorithm(); + }else { + encryptAlgorithm = JWEAlgorithm.DIR; + } + _logger.trace(" encryptAlgorithm {}" , encryptAlgorithm); + EncryptionMethod encryptionMethod = + jwtEncryptionService.parseEncryptionMethod(clientDetails.getEncryptionMethod()); + + Payload payload = builder.build().toPayload(); + // Example Request JWT encrypted with RSA-OAEP-256 and 128-bit AES/GCM + //JWEHeader jweHeader = new JWEHeader(JWEAlgorithm.RSA1_5, EncryptionMethod.A128GCM); + JWEObject jweObject = new JWEObject( + new JWEHeader.Builder(new JWEHeader(encryptAlgorithm,encryptionMethod)) + .contentType("JWT") // required to indicate nested JWT + .build(), + payload); + jwtEncryptionService.encryptJwt(jweObject); + idTokenString = jweObject.serialize(); + } catch (NoSuchAlgorithmException | InvalidKeySpecException | JOSEException e) { + _logger.error("Couldn't create Jwt Encryption Exception", e); + } + }else { + //not need a PlainJWT idToken + //JWT idToken = new PlainJWT(builder.build()); + //idTokenString = idToken.serialize(); } - logger.debug("idToken "+idToken); accessToken = new DefaultOAuth2AccessToken(accessToken); - if(idToken!=null){ - accessToken.getAdditionalInformation().put("id_token", idToken.serialize()); + if(StringUtils.isNotBlank(idTokenString)){ + accessToken.getAdditionalInformation().put("id_token", idTokenString); } } return accessToken; diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/autoconfigure/Oauth20AutoConfiguration.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/autoconfigure/Oauth20AutoConfiguration.java index 15e64a6c..328a06ac 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/autoconfigure/Oauth20AutoConfiguration.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/autoconfigure/Oauth20AutoConfiguration.java @@ -166,13 +166,9 @@ public class Oauth20AutoConfiguration implements InitializingBean { */ @Bean(name = "tokenEnhancer") public OIDCIdTokenEnhancer tokenEnhancer( - DefaultJwtSigningAndValidationService jwtSignerValidationService, - DefaultJwtEncryptionAndDecryptionService jwtEncryptionService, OIDCProviderMetadataDetails oidcProviderMetadata, ClientDetailsService oauth20JdbcClientDetailsService) { OIDCIdTokenEnhancer tokenEnhancer = new OIDCIdTokenEnhancer(); - tokenEnhancer.setJwtSignerService(jwtSignerValidationService); - tokenEnhancer.setJwtEnDecryptionService(jwtEncryptionService); tokenEnhancer.setClientDetailsService(oauth20JdbcClientDetailsService); tokenEnhancer.setProviderMetadata(oidcProviderMetadata); _logger.debug("OIDC IdToken Enhancer init."); diff --git a/maxkey-protocols/maxkey-protocol-tokenbased/src/main/java/org/maxkey/authz/token/endpoint/TokenBasedAuthorizeEndpoint.java b/maxkey-protocols/maxkey-protocol-tokenbased/src/main/java/org/maxkey/authz/token/endpoint/TokenBasedAuthorizeEndpoint.java index b37e4b62..36b2d535 100644 --- a/maxkey-protocols/maxkey-protocol-tokenbased/src/main/java/org/maxkey/authz/token/endpoint/TokenBasedAuthorizeEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-tokenbased/src/main/java/org/maxkey/authz/token/endpoint/TokenBasedAuthorizeEndpoint.java @@ -57,9 +57,7 @@ public class TokenBasedAuthorizeEndpoint extends AuthorizeBaseEndpoint{ final static Logger _logger = LoggerFactory.getLogger(TokenBasedAuthorizeEndpoint.class); @Autowired AppsTokenBasedDetailsService tokenBasedDetailsService; - - TokenBasedDefaultAdapter defaultTokenBasedAdapter=new TokenBasedDefaultAdapter(); - + @Autowired ApplicationConfig applicationConfig; @@ -84,42 +82,28 @@ public class TokenBasedAuthorizeEndpoint extends AuthorizeBaseEndpoint{ if(ConstsBoolean.isTrue(tokenBasedDetails.getIsAdapter())){ adapter =(AbstractAuthorizeAdapter)Instance.newInstance(tokenBasedDetails.getAdapter()); }else{ - adapter =(AbstractAuthorizeAdapter)defaultTokenBasedAdapter; + adapter =(AbstractAuthorizeAdapter)new TokenBasedDefaultAdapter(); } + adapter.setAuthentication((SigninPrincipal)WebContext.getAuthentication().getPrincipal()); + adapter.setUserInfo(WebContext.getUserInfo()); + adapter.setApp(tokenBasedDetails); - String tokenData=adapter.generateInfo( - (SigninPrincipal)WebContext.getAuthentication().getPrincipal(), - WebContext.getUserInfo(), - tokenBasedDetails); + adapter.generateInfo(); - String encryptTokenData=adapter.encrypt( - tokenData, + adapter.encrypt( + null, tokenBasedDetails.getAlgorithmKey(), tokenBasedDetails.getAlgorithm()); - String signTokenData=adapter.sign( - encryptTokenData, - tokenBasedDetails); - if(tokenBasedDetails.getTokenType().equalsIgnoreCase("POST")) { - modelAndView=adapter.authorize( - WebContext.getUserInfo(), - tokenBasedDetails, - signTokenData, - modelAndView); - - return modelAndView; + return adapter.authorize(modelAndView); }else { + _logger.debug("Cookie Name : {}" ,tokenBasedDetails.getCookieName()); - String cookieValue=""; - cookieValue=signTokenData; + Cookie cookie= new Cookie(tokenBasedDetails.getCookieName(),adapter.serialize()); - _logger.debug("Cookie Name : "+tokenBasedDetails.getCookieName()); - - Cookie cookie= new Cookie(tokenBasedDetails.getCookieName(),cookieValue); - - Integer maxAge=Integer.parseInt(tokenBasedDetails.getExpires())*60; - _logger.debug("Cookie Max Age :"+maxAge+" seconds."); + Integer maxAge=Integer.parseInt(tokenBasedDetails.getExpires()) * 60; + _logger.debug("Cookie Max Age : {} seconds.",maxAge); cookie.setMaxAge(maxAge); cookie.setPath("/"); @@ -128,7 +112,7 @@ public class TokenBasedAuthorizeEndpoint extends AuthorizeBaseEndpoint{ //tomcat 8.5 cookie.setDomain(applicationConfig.getBaseDomainName()); - _logger.debug("Sub Domain Name : "+"."+applicationConfig.getBaseDomainName()); + _logger.debug("Sub Domain Name : .{}",applicationConfig.getBaseDomainName()); response.addCookie(cookie); if(tokenBasedDetails.getRedirectUri().indexOf(applicationConfig.getBaseDomainName())>-1){ diff --git a/maxkey-protocols/maxkey-protocol-tokenbased/src/main/java/org/maxkey/authz/token/endpoint/adapter/TokenBasedDefaultAdapter.java b/maxkey-protocols/maxkey-protocol-tokenbased/src/main/java/org/maxkey/authz/token/endpoint/adapter/TokenBasedDefaultAdapter.java index 9733ec92..717807a8 100644 --- a/maxkey-protocols/maxkey-protocol-tokenbased/src/main/java/org/maxkey/authz/token/endpoint/adapter/TokenBasedDefaultAdapter.java +++ b/maxkey-protocols/maxkey-protocol-tokenbased/src/main/java/org/maxkey/authz/token/endpoint/adapter/TokenBasedDefaultAdapter.java @@ -20,9 +20,7 @@ package org.maxkey.authz.token.endpoint.adapter; import java.util.Date; import java.util.HashMap; -import org.maxkey.authn.SigninPrincipal; import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; -import org.maxkey.entity.UserInfo; import org.maxkey.entity.apps.AppsTokenBasedDetails; import org.maxkey.util.DateUtils; import org.maxkey.util.JsonUtils; @@ -34,8 +32,10 @@ import org.springframework.web.servlet.ModelAndView; public class TokenBasedDefaultAdapter extends AbstractAuthorizeAdapter { final static Logger _logger = LoggerFactory.getLogger(TokenBasedDefaultAdapter.class); + String token = ""; + @Override - public String generateInfo(SigninPrincipal authentication,UserInfo userInfo,Object app) { + public Object generateInfo() { AppsTokenBasedDetails details=(AppsTokenBasedDetails)app; HashMap beanMap=new HashMap(); @@ -90,24 +90,31 @@ public class TokenBasedDefaultAdapter extends AbstractAuthorizeAdapter { beanMap.put("expires", expiresString); - String jsonString=JsonUtils.object2Json(beanMap); - _logger.debug("Token : "+jsonString); + token = JsonUtils.object2Json(beanMap); + _logger.debug("Token : {}",token); - return jsonString; + return token; } @Override - public String encrypt(String data, String algorithmKey, String algorithm) { - return super.encrypt(data, algorithmKey, algorithm); + public Object encrypt(Object data, String algorithmKey, String algorithm) { + token = super.encrypt(token, algorithmKey, algorithm).toString(); + return token; } @Override - public ModelAndView authorize(UserInfo userInfo, Object app, String data,ModelAndView modelAndView) { + public ModelAndView authorize(ModelAndView modelAndView) { modelAndView.setViewName("authorize/tokenbased_sso_submint"); AppsTokenBasedDetails details=(AppsTokenBasedDetails)app; modelAndView.addObject("action", details.getRedirectUri()); - modelAndView.addObject("token",data ); + modelAndView.addObject("token",token ); return modelAndView; } + + @Override + public String serialize() { + return token; + } + } diff --git a/maxkey-protocols/maxkey-protocol-tokenbased/src/main/java/org/maxkey/authz/token/endpoint/adapter/TokenBasedSimpleAdapter.java b/maxkey-protocols/maxkey-protocol-tokenbased/src/main/java/org/maxkey/authz/token/endpoint/adapter/TokenBasedSimpleAdapter.java index 94ad4bc4..42000253 100644 --- a/maxkey-protocols/maxkey-protocol-tokenbased/src/main/java/org/maxkey/authz/token/endpoint/adapter/TokenBasedSimpleAdapter.java +++ b/maxkey-protocols/maxkey-protocol-tokenbased/src/main/java/org/maxkey/authz/token/endpoint/adapter/TokenBasedSimpleAdapter.java @@ -19,9 +19,7 @@ package org.maxkey.authz.token.endpoint.adapter; import java.util.Date; -import org.maxkey.authn.SigninPrincipal; import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; -import org.maxkey.entity.UserInfo; import org.maxkey.entity.apps.AppsTokenBasedDetails; import org.maxkey.util.DateUtils; import org.slf4j.Logger; @@ -30,8 +28,10 @@ import org.springframework.web.servlet.ModelAndView; public class TokenBasedSimpleAdapter extends AbstractAuthorizeAdapter { final static Logger _logger = LoggerFactory.getLogger(TokenBasedSimpleAdapter.class); + String token = ""; + @Override - public String generateInfo(SigninPrincipal authentication,UserInfo userInfo,Object app) { + public Object generateInfo() { AppsTokenBasedDetails details=(AppsTokenBasedDetails)app; String tokenUsername = userInfo.getUsername(); @@ -62,26 +62,31 @@ public class TokenBasedSimpleAdapter extends AbstractAuthorizeAdapter { _logger.debug("UTC current Date : "+DateUtils.toUtc(currentDate)); - String tokenString=tokenUsername+"@@"+DateUtils.toUtc(currentDate); - _logger.debug("Token : "+tokenString); + token = tokenUsername+"@@"+DateUtils.toUtc(currentDate); + _logger.debug("Token : {}",token); - return tokenString; + return token; } @Override - public String encrypt(String data, String algorithmKey, String algorithm) { - return super.encrypt(data, algorithmKey, algorithm); + public Object encrypt(Object data, String algorithmKey, String algorithm) { + token = super.encrypt(token, algorithmKey, algorithm).toString(); + return token; } @Override - public ModelAndView authorize(UserInfo userInfo, Object app, String data,ModelAndView modelAndView) { + public ModelAndView authorize(ModelAndView modelAndView) { modelAndView.setViewName("authorize/tokenbased_sso_submint"); AppsTokenBasedDetails details=(AppsTokenBasedDetails)app; modelAndView.addObject("action", details.getRedirectUri()); - modelAndView.addObject("token",data); + modelAndView.addObject("token",token); return modelAndView; } + @Override + public String serialize() { + return token; + } } diff --git a/maxkey-webs/maxkey-web-maxkey/src/main/resources/templates/views/authorize/jwt_sso_submint.ftl b/maxkey-webs/maxkey-web-maxkey/src/main/resources/templates/views/authorize/jwt_sso_submint.ftl index c460cdf8..cc91ea7e 100644 --- a/maxkey-webs/maxkey-web-maxkey/src/main/resources/templates/views/authorize/jwt_sso_submint.ftl +++ b/maxkey-webs/maxkey-web-maxkey/src/main/resources/templates/views/authorize/jwt_sso_submint.ftl @@ -11,7 +11,7 @@ - + diff --git a/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/ApplicationsController.java b/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/ApplicationsController.java index 9f1d0f11..434341d6 100644 --- a/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/ApplicationsController.java +++ b/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/ApplicationsController.java @@ -37,6 +37,16 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.JWEAlgorithm; +import com.nimbusds.jose.JWSAlgorithm; +import com.nimbusds.jose.Requirement; +import com.nimbusds.jose.jwk.KeyUse; +import com.nimbusds.jose.jwk.OctetSequenceKey; +import com.nimbusds.jose.jwk.RSAKey; +import com.nimbusds.jose.jwk.gen.OctetSequenceKeyGenerator; +import com.nimbusds.jose.jwk.gen.RSAKeyGenerator; + @Controller @RequestMapping(value={"/apps"}) @@ -177,7 +187,7 @@ public class ApplicationsController extends BaseAppContorller { @ResponseBody @RequestMapping(value = { "/generate/secret/{type}" }) - public String generateSecret(@PathVariable("type") String type) { + public String generateSecret(@PathVariable("type") String type,@RequestParam(name="id",required=false) String id) throws JOSEException { String secret=""; type=type.toLowerCase(); if(type.equals("des")){ @@ -188,6 +198,46 @@ public class ApplicationsController extends BaseAppContorller { secret=ReciprocalUtils.generateKey(ReciprocalUtils.Algorithm.AES); }else if(type.equals("blowfish")){ secret=ReciprocalUtils.generateKey(ReciprocalUtils.Algorithm.Blowfish); + }else if(type.equalsIgnoreCase("RS256") + ||type.equalsIgnoreCase("RS384") + ||type.equalsIgnoreCase("RS512")) { + RSAKey rsaJWK = new RSAKeyGenerator(2048) + .keyID(id + "_sig") + .keyUse(KeyUse.SIGNATURE) + .algorithm(new JWSAlgorithm(type.toUpperCase(), Requirement.OPTIONAL)) + .generate(); + secret = rsaJWK.toJSONString(); + }else if(type.equalsIgnoreCase("HS256") + ||type.equalsIgnoreCase("HS384") + ||type.equalsIgnoreCase("HS512")) { + OctetSequenceKey octKey= new OctetSequenceKeyGenerator(2048) + .keyID(id + "_sig") + .keyUse(KeyUse.SIGNATURE) + .algorithm(new JWSAlgorithm(type.toUpperCase(), Requirement.OPTIONAL)) + .generate(); + secret = octKey.toJSONString(); + }else if(type.equalsIgnoreCase("RSA1_5") + ||type.equalsIgnoreCase("RSA_OAEP") + ||type.equalsIgnoreCase("RSA-OAEP-256")) { + RSAKey rsaJWK = new RSAKeyGenerator(2048) + .keyID(id + "_enc") + .keyUse(KeyUse.ENCRYPTION) + .algorithm(new JWEAlgorithm(type.toUpperCase(), Requirement.OPTIONAL)) + .generate(); + secret = rsaJWK.toJSONString(); + }else if(type.equalsIgnoreCase("A128KW") + ||type.equalsIgnoreCase("A192KW") + ||type.equalsIgnoreCase("A256KW") + ||type.equalsIgnoreCase("A128GCMKW") + ||type.equalsIgnoreCase("A192GCMKW") + ||type.equalsIgnoreCase("A256GCMKW")) { + int keyLength = Integer.parseInt(type.substring(1, 4)); + OctetSequenceKey octKey= new OctetSequenceKeyGenerator(keyLength) + .keyID(id + "_enc") + .keyUse(KeyUse.ENCRYPTION) + .algorithm(new JWEAlgorithm(type.toUpperCase(), Requirement.OPTIONAL)) + .generate(); + secret = octKey.toJSONString(); }else{ secret=ReciprocalUtils.generateKey(""); } diff --git a/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/BasicDetailsController.java b/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/BasicDetailsController.java index 972f7db0..9d1b3370 100644 --- a/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/BasicDetailsController.java +++ b/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/BasicDetailsController.java @@ -46,7 +46,7 @@ public class BasicDetailsController extends BaseAppContorller { Apps appDetails =new Apps(); appDetails.setId(appDetails.generateId()); appDetails.setProtocol(ConstsProtocols.BASIC); - appDetails.setSecret(ReciprocalUtils.generateKey(ReciprocalUtils.Algorithm.DES)); + appDetails.setSecret(ReciprocalUtils.generateKey("")); modelAndView.addObject("model",appDetails); return modelAndView; } diff --git a/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/CasDetailsController.java b/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/CasDetailsController.java index 5970803b..692c8350 100644 --- a/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/CasDetailsController.java +++ b/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/CasDetailsController.java @@ -50,7 +50,7 @@ public class CasDetailsController extends BaseAppContorller { AppsCasDetails casDetails =new AppsCasDetails(); casDetails.setId(casDetails.generateId()); casDetails.setProtocol(ConstsProtocols.CAS); - casDetails.setSecret(ReciprocalUtils.generateKey(ReciprocalUtils.Algorithm.DES)); + casDetails.setSecret(ReciprocalUtils.generateKey("")); modelAndView.addObject("model",casDetails); return modelAndView; } diff --git a/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/JwtDetailsController.java b/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/JwtDetailsController.java index 71a81ed4..a5bf2d33 100644 --- a/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/JwtDetailsController.java +++ b/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/JwtDetailsController.java @@ -52,7 +52,6 @@ public class JwtDetailsController extends BaseAppContorller { jwtDetails.setId(jwtDetails.generateId()); jwtDetails.setProtocol(ConstsProtocols.JWT); jwtDetails.setSecret(ReciprocalUtils.generateKey(ReciprocalUtils.Algorithm.AES)); - jwtDetails.setAlgorithmKey(jwtDetails.getSecret()); jwtDetails.setUserPropertys("userPropertys"); modelAndView.addObject("model",jwtDetails); return modelAndView; @@ -65,7 +64,6 @@ public class JwtDetailsController extends BaseAppContorller { transform(jwtDetails); - jwtDetails.setAlgorithmKey(jwtDetails.getSecret()); jwtDetails.setInstId(WebContext.getUserInfo().getInstId()); if (jwtDetailsService.insert(jwtDetails)&&appsService.insertApp(jwtDetails)) { new Message(WebContext.getI18nValue(ConstsOperateMessage.INSERT_SUCCESS),MessageType.success); @@ -81,8 +79,6 @@ public class JwtDetailsController extends BaseAppContorller { ModelAndView modelAndView=new ModelAndView("apps/jwt/appUpdate"); AppsJwtDetails jwtDetails=jwtDetailsService.getAppDetails(id); decoderSecret(jwtDetails); - String algorithmKey=passwordReciprocal.decoder(jwtDetails.getAlgorithmKey()); - jwtDetails.setAlgorithmKey(algorithmKey); WebContext.setAttribute(jwtDetails.getId(), jwtDetails.getIcon()); modelAndView.addObject("model",jwtDetails); @@ -98,7 +94,6 @@ public class JwtDetailsController extends BaseAppContorller { // _logger.debug("-update application :" + jwtDetails); transform(jwtDetails); - jwtDetails.setAlgorithmKey(jwtDetails.getSecret()); jwtDetails.setInstId(WebContext.getUserInfo().getInstId()); if (jwtDetailsService.update(jwtDetails)&&appsService.updateApp(jwtDetails)) { new Message(WebContext.getI18nValue(ConstsOperateMessage.UPDATE_SUCCESS),MessageType.success); diff --git a/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/OAuth20DetailsController.java b/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/OAuth20DetailsController.java index ac30701c..8fce575e 100644 --- a/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/OAuth20DetailsController.java +++ b/maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/apps/contorller/OAuth20DetailsController.java @@ -87,7 +87,7 @@ public class OAuth20DetailsController extends BaseAppContorller { @RequestMapping(value = { "/forwardUpdate/{id}" }) public ModelAndView forwardUpdate(@PathVariable("id") String id) { ModelAndView modelAndView=new ModelAndView("apps/oauth20/appUpdate"); - BaseClientDetails baseClientDetails=(BaseClientDetails)oauth20JdbcClientDetailsService.loadClientByClientId(id); + BaseClientDetails baseClientDetails=(BaseClientDetails)oauth20JdbcClientDetailsService.loadClientByClientId(id,false); Apps application=appsService.get(id);// decoderSecret(application); AppsOAuth20Details oauth20Details=new AppsOAuth20Details(application,baseClientDetails); diff --git a/maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message.properties b/maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message.properties index 1217e1fa..3ba432d6 100644 --- a/maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message.properties +++ b/maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message.properties @@ -333,6 +333,7 @@ apps.formbased.parameter.value=\u53C2\u6570\u503C apps.cas.info=CAS\u8BA4\u8BC1 apps.cas.service=\u670D\u52A1 apps.cas.callbackUrl=\u56DE\u8C03\u5730\u5740 +apps.cas.casUser=\u8FD4\u56DE\u8D26\u53F7 apps.cas.expires=\u8FC7\u671F\u65F6\u95F4 #tokenbased apps.tokenbased.info=\u4EE4\u724C\u8BA4\u8BC1 @@ -346,10 +347,16 @@ apps.tokenbased.expires=\u8FC7\u671F\u65F6\u95F4 #JWT apps.jwt.info=JWT\u8BA4\u8BC1 apps.jwt.redirectUri=\u8BA4\u8BC1\u5730\u5740 +apps.jwt.subject=\u4E3B\u9898(Subject) +apps.jwt.audience=\u53D7\u4F17(Audience) +apps.jwt.issuer=\u7B7E\u53D1\u4EBA(Issuer) apps.jwt.tokenType=\u4EE4\u724C\u7C7B\u578B -apps.jwt.cookieName=Cookie\u540D\u79F0 +apps.jwt.jwtName=\u540D\u79F0 apps.jwt.algorithm=\u52A0\u5BC6\u7B97\u6CD5 apps.jwt.algorithmKey=\u79D8\u94A5 +apps.jwt.encryptionMethod=\u52A0\u5BC6\u65B9\u6CD5 +apps.jwt.signature=\u7B7E\u540D\u7B97\u6CD5 +apps.jwt.signatureKey=\u7B7E\u540D\u5BC6\u94A5 apps.jwt.content=\u4EE4\u724C\u5185\u5BB9 apps.jwt.expires=\u8FC7\u671F\u65F6\u95F4 #SAML @@ -404,14 +411,17 @@ apps.oauth.approvalPrompt=\u8BB8\u53EF\u786E\u8BA4 apps.oauth.v2.0.info=OAuth 2.0 \u8BA4\u8BC1\u914D\u7F6E apps.oauth.GrantTypes=\u6388\u6743\u65B9\u5F0F apps.oauth.v2.0.clientId=Client Id +apps.oauth.subject=\u4E3B\u9898(Subject) apps.oauth.connect.info=OpenID Connect \u8BA4\u8BC1\u914D\u7F6E -apps.oauth.connect.idTokenSigningAlgorithm=idToken\u7B7E\u540D\u7B97\u6CD5 -apps.oauth.connect.userInfoSigningAlgorithm=\u7528\u6237\u7B7E\u540D\u7B97\u6CD5 -apps.oauth.connect.jwksUri=JWKS\u5730\u5740 -apps.oauth.connect.idTokenEncryptedAlgorithm=idToken\u52A0\u5BC6\u7B97\u6CD5 -apps.oauth.connect.userInfoEncryptedAlgorithm=\u7528\u6237\u52A0\u5BC6\u7B97\u6CD5 -apps.oauth.connect.idTokenEncryptionMethod=idToken\u52A0\u5BC6\u65B9\u6CD5 -apps.oauth.connect.userInfoEncryptionMethod=\u7528\u6237\u52A0\u5BC6\u65B9\u6CD5 +apps.oauth.connect.algorithm=\u52A0\u5BC6\u7B97\u6CD5 +apps.oauth.connect.algorithmKey=\u79D8\u94A5 +apps.oauth.connect.encryptionMethod=\u52A0\u5BC6\u65B9\u6CD5 +apps.oauth.connect.signature=\u7B7E\u540D\u7B97\u6CD5 +apps.oauth.connect.signatureKey=\u7B7E\u540D\u5BC6\u94A5 +apps.oauth.connect.audience=\u53D7\u4F17(Audience) +apps.oauth.connect.issuer=\u7B7E\u53D1\u4EBA(Issuer) +apps.oauth.connect.userInfoResponse=\u7528\u6237\u63A5\u53E3\u7C7B\u578B + #group group.id=\u7EC4\u7F16\u7801 group.name=\u7528\u6237\u7EC4 diff --git a/maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message_en.properties b/maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message_en.properties index 18e4b8cb..c155b910 100644 --- a/maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message_en.properties +++ b/maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message_en.properties @@ -338,6 +338,7 @@ apps.formbased.parameter.value=value apps.cas.info=CAS Info apps.cas.service=Service apps.cas.callbackUrl=CallbackUrl +apps.cas.casUser=CasUser apps.cas.expires=Expires #tokenbased apps.tokenbased.info=tokenbased Info @@ -351,10 +352,16 @@ apps.tokenbased.expires=expires #jwt apps.jwt.info=JWT Info apps.jwt.redirectUri=redirectUri +apps.jwt.subject=subject +apps.jwt.audience=audience +apps.jwt.issuer=issuer apps.jwt.tokenType=tokenType -apps.jwt.cookieName=Cookie Name +apps.jwt.jwtName=jwtName apps.jwt.algorithm=algorithm +apps.jwt.encryptionMethod=encryptionMethod apps.jwt.algorithmKey=algorithmKey +apps.jwt.signature=signature +apps.jwt.signatureKey=signatureKey apps.jwt.content=content apps.jwt.expires=expires #SAML @@ -409,14 +416,16 @@ apps.oauth.approvalPrompt=approvalPrompt apps.oauth.v2.0.info=OAuth 2.0 Info apps.oauth.GrantTypes=GrantTypes apps.oauth.v2.0.clientId=Client Id +apps.oauth.subject=Subject apps.oauth.connect.info=OpenID Connect Info -apps.oauth.connect.idTokenSigningAlgorithm=idTokenSigningAlgorithm -apps.oauth.connect.userInfoSigningAlgorithm=userInfoSigningAlgorithm -apps.oauth.connect.jwksUri=jwksUri -apps.oauth.connect.idTokenEncryptedAlgorithm=idTokenEncryptedAlgorithm -apps.oauth.connect.userInfoEncryptedAlgorithm=userInfoEncryptedAlgorithm -apps.oauth.connect.idTokenEncryptionMethod=idTokenEncryptionMethod -apps.oauth.connect.userInfoEncryptionMethod=idTokenEncryptionMethod +apps.oauth.connect.algorithm=Algorithm +apps.oauth.connect.algorithmKey=AlgorithmKey +apps.oauth.connect.encryptionMethod=EncryptionMethod +apps.oauth.connect.signature=Signature +apps.oauth.connect.signatureKey=SignatureKey +apps.oauth.connect.audience=Audience +apps.oauth.connect.issuer=Issuer +apps.oauth.connect.userInfoResponse=UserInfoResponse #group group.id=id diff --git a/maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message_zh_CN.properties b/maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message_zh_CN.properties index 6804e29e..82186ce1 100644 --- a/maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message_zh_CN.properties +++ b/maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message_zh_CN.properties @@ -333,6 +333,7 @@ apps.formbased.parameter.value=\u53C2\u6570\u503C apps.cas.info=CAS\u8BA4\u8BC1 apps.cas.service=\u670D\u52A1 apps.cas.callbackUrl=\u56DE\u8C03\u5730\u5740 +apps.cas.casUser=\u8FD4\u56DE\u8D26\u53F7 apps.cas.expires=\u8FC7\u671F\u65F6\u95F4 #tokenbased apps.tokenbased.info=\u4EE4\u724C\u8BA4\u8BC1 @@ -346,10 +347,16 @@ apps.tokenbased.expires=\u8FC7\u671F\u65F6\u95F4 #JWT apps.jwt.info=JWT\u8BA4\u8BC1 apps.jwt.redirectUri=\u8BA4\u8BC1\u5730\u5740 +apps.jwt.subject=\u4E3B\u9898(Subject) +apps.jwt.audience=\u53D7\u4F17(Audience) +apps.jwt.issuer=\u7B7E\u53D1\u4EBA(Issuer) apps.jwt.tokenType=\u4EE4\u724C\u7C7B\u578B -apps.jwt.cookieName=Cookie\u540D\u79F0 +apps.jwt.jwtName=\u540D\u79F0 apps.jwt.algorithm=\u52A0\u5BC6\u7B97\u6CD5 -apps.jwt.algorithmKey=\u79D8\u94A5 +apps.jwt.encryptionMethod=\u52A0\u5BC6\u65B9\u6CD5 +apps.jwt.algorithmKey=\u52A0\u5BC6\u79D8\u94A5 +apps.jwt.signature=\u7B7E\u540D\u7B97\u6CD5 +apps.jwt.signatureKey=\u7B7E\u540D\u5BC6\u94A5 apps.jwt.content=\u4EE4\u724C\u5185\u5BB9 apps.jwt.expires=\u8FC7\u671F\u65F6\u95F4 #SAML @@ -404,14 +411,16 @@ apps.oauth.approvalPrompt=\u8BB8\u53EF\u786E\u8BA4 apps.oauth.v2.0.info=OAuth 2.0 \u8BA4\u8BC1\u914D\u7F6E apps.oauth.GrantTypes=\u6388\u6743\u65B9\u5F0F apps.oauth.v2.0.clientId=Client Id +apps.oauth.subject=\u4E3B\u9898(Subject) apps.oauth.connect.info=OpenID Connect \u8BA4\u8BC1\u914D\u7F6E -apps.oauth.connect.idTokenSigningAlgorithm=idToken\u7B7E\u540D\u7B97\u6CD5 -apps.oauth.connect.userInfoSigningAlgorithm=\u7528\u6237\u7B7E\u540D\u7B97\u6CD5 -apps.oauth.connect.jwksUri=JWKS\u5730\u5740 -apps.oauth.connect.idTokenEncryptedAlgorithm=idToken\u52A0\u5BC6\u7B97\u6CD5 -apps.oauth.connect.userInfoEncryptedAlgorithm=\u7528\u6237\u52A0\u5BC6\u7B97\u6CD5 -apps.oauth.connect.idTokenEncryptionMethod=idToken\u52A0\u5BC6\u65B9\u6CD5 -apps.oauth.connect.userInfoEncryptionMethod=\u7528\u6237\u52A0\u5BC6\u65B9\u6CD5 +apps.oauth.connect.algorithm=\u52A0\u5BC6\u7B97\u6CD5 +apps.oauth.connect.algorithmKey=\u79D8\u94A5 +apps.oauth.connect.encryptionMethod=\u52A0\u5BC6\u65B9\u6CD5 +apps.oauth.connect.signature=\u7B7E\u540D\u7B97\u6CD5 +apps.oauth.connect.signatureKey=\u7B7E\u540D\u5BC6\u94A5 +apps.oauth.connect.audience=\u53D7\u4F17(Audience) +apps.oauth.connect.issuer=\u7B7E\u53D1\u4EBA(Issuer) +apps.oauth.connect.userInfoResponse=\u7528\u6237\u63A5\u53E3\u7C7B\u578B #group group.id=\u7EC4\u7F16\u7801 group.name=\u7528\u6237\u7EC4 diff --git a/maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/apps/appAddCommon.ftl b/maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/apps/appAddCommon.ftl index b86d6171..d1b86379 100644 --- a/maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/apps/appAddCommon.ftl +++ b/maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/apps/appAddCommon.ftl @@ -24,13 +24,13 @@ - + - + diff --git a/maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/apps/appCommonHead.ftl b/maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/apps/appCommonHead.ftl index 1efafa20..669fbaf2 100644 --- a/maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/apps/appCommonHead.ftl +++ b/maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/apps/appCommonHead.ftl @@ -8,18 +8,27 @@
token
<@locale code="apps.loginUrl"/>
<@locale code="apps.loginUrl"/><@locale code="apps.logoutUrl"/>