diff --git a/maxkey-persistence/src/test/resources/application.properties b/maxkey-persistence/src/test/resources/application.properties index bee05d5d3..20d8b2132 100644 --- a/maxkey-persistence/src/test/resources/application.properties +++ b/maxkey-persistence/src/test/resources/application.properties @@ -207,8 +207,8 @@ maxkey.support.wsfederation.logoutUrl=https://adfs.maxkey.top/adfs/ls/?wa=wsigno ############################################################################# # OIDC V1.0 METADATA configuration maxkey.oidc.metadata.issuer=${maxkey.server.name}/maxkey -maxkey.oidc.metadata.authorizationEndpoint=${maxkey.server.name}/maxkey/oauth/v20/authorize -maxkey.oidc.metadata.tokenEndpoint=${maxkey.server.name}/maxkey/oauth/v20/token +maxkey.oidc.metadata.authorizationEndpoint=${maxkey.server.name}/maxkey/authz/oauth/v20/authorize +maxkey.oidc.metadata.tokenEndpoint=${maxkey.server.name}/maxkey/authz/oauth/v20/token maxkey.oidc.metadata.userinfoEndpoint=${maxkey.server.name}/maxkey/api/connect/userinfo ############################################################################# diff --git a/maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/endpoint/AuthorizeEndpoint.java b/maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/endpoint/AuthorizeEndpoint.java index bc6de5795..eacbb108f 100644 --- a/maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/endpoint/AuthorizeEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/endpoint/AuthorizeEndpoint.java @@ -64,7 +64,7 @@ public class AuthorizeEndpoint extends AuthorizeBaseEndpoint{ }else if (application.getProtocol().equalsIgnoreCase(ConstantsProtocols.FORMBASED)){ modelAndView=WebContext.forward("/authz/formbased/"+id); }else if (application.getProtocol().equalsIgnoreCase(ConstantsProtocols.OAUTH20)){ - modelAndView=WebContext.forward("/authz/oauthv20/"+application.getId()); + modelAndView=WebContext.forward("/authz/oauth/v20/"+application.getId()); }else if (application.getProtocol().equalsIgnoreCase(ConstantsProtocols.OPEN_ID_CONNECT)){ // modelAndView=new ModelAndView("openid connect"); }else if (application.getProtocol().equalsIgnoreCase(ConstantsProtocols.SAML20)){ diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/common/OAuth2Constants.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/common/OAuth2Constants.java new file mode 100644 index 000000000..ead89c0b3 --- /dev/null +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/common/OAuth2Constants.java @@ -0,0 +1,76 @@ +package org.maxkey.authz.oauth2.common; + +public class OAuth2Constants { + + public static final class PARAMETER{ + /** + * Constant to use while parsing and formatting parameter maps for OAuth2 requests + */ + public static final String CLIENT_ID = "client_id"; + + public static final String CLIENT_SECRET = "client_secret"; + + /** + * Constant to use while parsing and formatting parameter maps for OAuth2 requests + */ + public static final String STATE = "state"; + + /** + * Constant to use while parsing and formatting parameter maps for OAuth2 requests + */ + public static final String SCOPE = "scope"; + + public static final String CODE = "code"; + + public static final String EXPIRES_IN = "expires_in"; + + /** + * Constant to use while parsing and formatting parameter maps for OAuth2 requests + */ + public static final String REDIRECT_URI = "redirect_uri"; + + /** + * Constant to use while parsing and formatting parameter maps for OAuth2 requests + */ + public static final String RESPONSE_TYPE = "response_type"; + + /** + * Constant to use while parsing and formatting parameter maps for OAuth2 requests + */ + public static final String USER_OAUTH_APPROVAL = "user_oauth_approval"; + + /** + * Constant to use as a prefix for scope approval + */ + public static final String SCOPE_PREFIX = "scope."; + + /** + * Constant to use while parsing and formatting parameter maps for OAuth2 requests + */ + public static final String GRANT_TYPE = "grant_type"; + + public static final String ACCESS_TOKEN = "access_token"; + } + + public static class ENDPOINT{ + + public final static String ENDPOINT_BASE = "/authz/oauth/v20"; + + public final static String ENDPOINT_AUTHORIZE = ENDPOINT_BASE + "/authorize"; + + public final static String ENDPOINT_TOKEN = ENDPOINT_BASE + "/token"; + + public final static String ENDPOINT_CHECK_TOKEN = ENDPOINT_BASE + "/check_token"; + + public final static String ENDPOINT_TOKEN_KEY = ENDPOINT_BASE + "/token_key"; + + public final static String ENDPOINT_APPROVAL_CONFIRM = ENDPOINT_BASE + "/approval_confirm"; + + public final static String ENDPOINT_ERROR = ENDPOINT_BASE + "/error"; + + public final static String ENDPOINT_USERINFO = "/api/oauth/v20/me"; + + public final static String ENDPOINT_OPENID_CONNECT_USERINFO = "/api/connect/v10/userinfo"; + + } +} diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/controller/OAuth20AccessConfirmationController.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/controller/OAuth20AccessConfirmationController.java index 962fb6eb4..866f8595a 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/controller/OAuth20AccessConfirmationController.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/approval/controller/OAuth20AccessConfirmationController.java @@ -22,6 +22,7 @@ import java.util.LinkedHashMap; import java.util.Map; import org.maxkey.authn.SigninPrincipal; import org.maxkey.authz.endpoint.AuthorizeBaseEndpoint; +import org.maxkey.authz.oauth2.common.OAuth2Constants; import org.maxkey.authz.oauth2.common.util.OAuth2Utils; import org.maxkey.authz.oauth2.provider.AuthorizationRequest; import org.maxkey.authz.oauth2.provider.ClientDetailsService; @@ -73,7 +74,7 @@ public class OAuth20AccessConfirmationController { * @return * throws Exception */ - @RequestMapping("/oauth/v20/approval_confirm") + @RequestMapping(OAuth2Constants.ENDPOINT.ENDPOINT_APPROVAL_CONFIRM) public ModelAndView getAccessConfirmation( @RequestParam Map model) throws Exception { model.remove("authorizationRequest"); @@ -123,7 +124,7 @@ public class OAuth20AccessConfirmationController { * @return * throws Exception */ - @RequestMapping("/oauth/v20/error") + @RequestMapping(OAuth2Constants.ENDPOINT.ENDPOINT_ERROR) public String handleError(Map model) throws Exception { // We can add more stuff to the model here for JSP rendering. If the client was // a machine then 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 3e2d8717d..92922f37e 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 @@ -25,6 +25,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.maxkey.authz.oauth2.common.OAuth2AccessToken; +import org.maxkey.authz.oauth2.common.OAuth2Constants; import org.maxkey.authz.oauth2.common.exceptions.InvalidClientException; import org.maxkey.authz.oauth2.common.exceptions.InvalidRequestException; import org.maxkey.authz.oauth2.common.exceptions.OAuth2Exception; @@ -99,7 +100,7 @@ import org.maxkey.authz.oauth2.provider.ClientDetailsService; public class AuthorizationEndpoint extends AbstractEndpoint { final static Logger _logger = LoggerFactory.getLogger(AuthorizationEndpoint.class); - private static final String OAUTH_V20_AUTHORIZATION_URL = "%s/oauth/v20/authorize?client_id=%s&response_type=code&redirect_uri=%s&approval_prompt=auto"; + private static final String OAUTH_V20_AUTHORIZATION_URL = "%s" + OAuth2Constants.ENDPOINT.ENDPOINT_AUTHORIZE + "?client_id=%s&response_type=code&redirect_uri=%s&approval_prompt=auto"; @Autowired @Qualifier("oauth20JdbcClientDetailsService") @@ -117,9 +118,9 @@ public class AuthorizationEndpoint extends AbstractEndpoint { private OAuth2RequestValidator oauth2RequestValidator = new DefaultOAuth2RequestValidator(); - private String userApprovalPage = "forward:/oauth/v20/approval_confirm"; + private String userApprovalPage = "forward:" + OAuth2Constants.ENDPOINT.ENDPOINT_APPROVAL_CONFIRM; - private String errorPage = "forward:/oauth/error"; + private String errorPage = "forward:" + OAuth2Constants.ENDPOINT.ENDPOINT_ERROR; private Object implicitLock = new Object(); @@ -132,7 +133,7 @@ public class AuthorizationEndpoint extends AbstractEndpoint { } @ApiOperation(value = "OAuth 2.0 认证接口", notes = "传递参数client_id,response_type,redirect_uri等",httpMethod="GET") - @RequestMapping(value = "/oauth/v20/authorize", method = RequestMethod.GET) + @RequestMapping(value = OAuth2Constants.ENDPOINT.ENDPOINT_AUTHORIZE, method = RequestMethod.GET) public ModelAndView authorize(Map model, @RequestParam Map parameters, SessionStatus sessionStatus) { Principal principal=(Principal)WebContext.getAuthentication(); @@ -211,7 +212,7 @@ public class AuthorizationEndpoint extends AbstractEndpoint { } - @RequestMapping(value = "/oauth/v20/authorize", method = RequestMethod.POST, params = OAuth2Utils.USER_OAUTH_APPROVAL) + @RequestMapping(value = OAuth2Constants.ENDPOINT.ENDPOINT_AUTHORIZE, method = RequestMethod.POST, params = OAuth2Utils.USER_OAUTH_APPROVAL) public View approveOrDeny(@RequestParam Map approvalParameters, Map model, SessionStatus sessionStatus) { Principal principal=(Principal)WebContext.getAuthentication(); @@ -514,7 +515,7 @@ public class AuthorizationEndpoint extends AbstractEndpoint { } @ApiOperation(value = "OAuth 2.0 认证接口", notes = "传递参数应用ID,自动完成跳转认证拼接",httpMethod="GET") - @RequestMapping("/authz/oauthv20/{id}") + @RequestMapping(OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/{id}") public ModelAndView authorize( HttpServletRequest request, HttpServletResponse response, diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/CheckTokenEndpoint.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/CheckTokenEndpoint.java index 9b2144fbe..b352821ca 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/CheckTokenEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/CheckTokenEndpoint.java @@ -34,6 +34,7 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.maxkey.authz.oauth2.common.OAuth2AccessToken; +import org.maxkey.authz.oauth2.common.OAuth2Constants; import org.maxkey.authz.oauth2.common.exceptions.InvalidTokenException; import org.maxkey.authz.oauth2.common.exceptions.OAuth2Exception; import org.maxkey.authz.oauth2.provider.OAuth2Authentication; @@ -81,7 +82,7 @@ public class CheckTokenEndpoint { } @ApiOperation(value = "OAuth 2.0 token检查接口", notes = "传递参数token",httpMethod="POST") - @RequestMapping(value = "/oauth/v20/check_token") + @RequestMapping(value = OAuth2Constants.ENDPOINT.ENDPOINT_CHECK_TOKEN) @ResponseBody public Map checkToken(@RequestParam("token") String value) { 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 80b8e5f2a..0f5d165a3 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 @@ -25,6 +25,7 @@ import java.util.Set; import org.maxkey.authn.SigninPrincipal; import org.maxkey.authz.oauth2.common.DefaultOAuth2AccessToken; import org.maxkey.authz.oauth2.common.OAuth2AccessToken; +import org.maxkey.authz.oauth2.common.OAuth2Constants; import org.maxkey.authz.oauth2.common.exceptions.InvalidClientException; import org.maxkey.authz.oauth2.common.exceptions.InvalidGrantException; import org.maxkey.authz.oauth2.common.exceptions.InvalidRequestException; @@ -89,7 +90,7 @@ public class TokenEndpoint extends AbstractEndpoint { * @throws HttpRequestMethodNotSupportedException */ @ApiOperation(value = "OAuth 2.0 获取AccessToken接口", notes = "传递参数token等",httpMethod="GET") - @RequestMapping(value = "/oauth/v20/token", method=RequestMethod.GET) + @RequestMapping(value = OAuth2Constants.ENDPOINT.ENDPOINT_TOKEN, method=RequestMethod.GET) public ResponseEntity getAccessToken(@RequestParam Map parameters) throws HttpRequestMethodNotSupportedException { if (!allowedRequestMethods.contains(HttpMethod.GET)) { @@ -99,7 +100,7 @@ public class TokenEndpoint extends AbstractEndpoint { } @ApiOperation(value = "OAuth 2.0 获取AccessToken接口", notes = "传递参数token等",httpMethod="POST") - @RequestMapping(value = "/oauth/v20/token", method=RequestMethod.POST) + @RequestMapping(value = OAuth2Constants.ENDPOINT.ENDPOINT_TOKEN, method=RequestMethod.POST) public ResponseEntity postAccessToken(@RequestParam Map parameters) throws HttpRequestMethodNotSupportedException { // TokenEndpointAuthenticationFilter diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpointAuthenticationFilter.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpointAuthenticationFilter.java index c1d230fd8..6a4a51552 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpointAuthenticationFilter.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpointAuthenticationFilter.java @@ -35,6 +35,7 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.maxkey.authn.SigninPrincipal; +import org.maxkey.authz.oauth2.common.OAuth2Constants; import org.maxkey.authz.oauth2.common.util.OAuth2Utils; import org.maxkey.authz.oauth2.provider.AuthorizationRequest; import org.maxkey.authz.oauth2.provider.OAuth2Authentication; @@ -77,7 +78,7 @@ import org.springframework.web.HttpRequestMethodNotSupportedException; * @author Dave Syer * */ -@WebFilter(filterName = "TokenEndpointAuthenticationFilter", urlPatterns = "/oauth/v20/token/*") +@WebFilter(filterName = "TokenEndpointAuthenticationFilter", urlPatterns = OAuth2Constants.ENDPOINT.ENDPOINT_TOKEN+"/*") public class TokenEndpointAuthenticationFilter implements Filter { private static final Log logger = LogFactory.getLog(TokenEndpointAuthenticationFilter.class); diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenKeyEndpoint.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenKeyEndpoint.java index 5bfc15146..40a0ffbda 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenKeyEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenKeyEndpoint.java @@ -34,6 +34,7 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.maxkey.authz.oauth2.common.OAuth2Constants; import org.maxkey.authz.oauth2.provider.token.store.JwtAccessTokenConverter; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.authentication.AnonymousAuthenticationToken; @@ -69,7 +70,7 @@ public class TokenKeyEndpoint { * @param principal the currently authenticated user if there is one * @return the key used to verify tokens */ - @RequestMapping(value = "/oauth/token_key", method = RequestMethod.GET) + @RequestMapping(value = OAuth2Constants.ENDPOINT.ENDPOINT_TOKEN_KEY, method = RequestMethod.GET) @ResponseBody public Map getKey(Principal principal) { if ((principal == null || principal instanceof AnonymousAuthenticationToken) && !converter.isPublic()) { 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/OpenIdConnectUserInfoEndpoint.java new file mode 100644 index 000000000..2eb6f1363 --- /dev/null +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/OpenIdConnectUserInfoEndpoint.java @@ -0,0 +1,302 @@ +/* + * 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.oauth2.provider.userinfo.endpoint; + +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.Set; +import java.util.UUID; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.maxkey.authn.SigninPrincipal; +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.ReciprocalUtils; +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.domain.UserInfo; +import org.maxkey.domain.apps.oauth2.provider.ClientDetails; +import org.maxkey.persistence.service.AppsService; +import org.maxkey.persistence.service.UserInfoService; +import org.maxkey.util.JsonUtils; +import org.maxkey.util.StringGenerator; +import org.maxkey.web.HttpResponseAdapter; +import org.maxkey.web.WebConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.nimbusds.jose.EncryptionMethod; +import com.nimbusds.jose.JWEAlgorithm; +import com.nimbusds.jose.JWEHeader; +import com.nimbusds.jose.JWSAlgorithm; +import com.nimbusds.jose.JWSHeader; +import com.nimbusds.jwt.EncryptedJWT; +import com.nimbusds.jwt.JWT; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.JWTClaimsSet.Builder; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import com.nimbusds.jwt.SignedJWT; + +@Api(tags = "2-1-OAuth v2.0 API文档模块") +@Controller +public class OpenIdConnectUserInfoEndpoint { + final static Logger _logger = LoggerFactory.getLogger(OpenIdConnectUserInfoEndpoint.class); + @Autowired + @Qualifier("oauth20JdbcClientDetailsService") + private ClientDetailsService clientDetailsService; + + @Autowired + @Qualifier("oauth20TokenServices") + private DefaultTokenServices oauth20tokenServices; + + + @Autowired + @Qualifier("userInfoService") + private UserInfoService userInfoService; + + @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; + + @ApiOperation(value = "OIDC 用户信息接口", notes = "传递Authorization参数access_token",httpMethod="GET") + @RequestMapping(value=OAuth2Constants.ENDPOINT.ENDPOINT_OPENID_CONNECT_USERINFO) + @ResponseBody + public String connect10aUserInfo( + @RequestHeader(value = "Authorization", required = true) String access_token, + HttpServletRequest request, + HttpServletResponse response) { + String principal=""; + if (!StringGenerator.uuidMatches(access_token)) { + return JsonUtils.gson2Json(accessTokenFormatError(access_token)); + } + + OAuth2Authentication oAuth2Authentication =null; + try{ + oAuth2Authentication = oauth20tokenServices.loadAuthentication(access_token); + + principal=((SigninPrincipal)oAuth2Authentication.getPrincipal()).getUsername(); + + Setscopes=oAuth2Authentication.getOAuth2Request().getScope(); + ClientDetails clientDetails = clientDetailsService.loadClientByClientId(oAuth2Authentication.getOAuth2Request().getClientId()); + + UserInfo userInfo=queryUserInfo(principal); + String userJson=""; + Builder jwtClaimsSetBuilder= new JWTClaimsSet.Builder(); + + SigninPrincipal authentication = (SigninPrincipal)oAuth2Authentication.getUserAuthentication().getPrincipal(); + + jwtClaimsSetBuilder.claim("sub", userInfo.getId()); + jwtClaimsSetBuilder.claim(WebConstants.ONLINE_TICKET_NAME, authentication.getOnlineTicket().getTicketId()); + + if(scopes.contains("profile")){ + jwtClaimsSetBuilder.claim("name", userInfo.getUsername()); + jwtClaimsSetBuilder.claim("preferred_username", userInfo.getDisplayName()); + jwtClaimsSetBuilder.claim("given_name", userInfo.getGivenName()); + jwtClaimsSetBuilder.claim("family_name", userInfo.getFamilyName()); + jwtClaimsSetBuilder.claim("middle_name", userInfo.getMiddleName()); + jwtClaimsSetBuilder.claim("nickname", userInfo.getNickName()); + jwtClaimsSetBuilder.claim("profile", "profile"); + jwtClaimsSetBuilder.claim("picture", "picture"); + jwtClaimsSetBuilder.claim("website", userInfo.getWebSite()); + + String gender; + switch(userInfo.getGender()){ + case UserInfo.GENDER.MALE : + gender="male";break; + case UserInfo.GENDER.FEMALE : + gender="female";break; + default: + gender="unknown"; + } + jwtClaimsSetBuilder.claim("gender", gender); + jwtClaimsSetBuilder.claim("zoneinfo", userInfo.getTimeZone()); + jwtClaimsSetBuilder.claim("locale", userInfo.getLocale()); + jwtClaimsSetBuilder.claim("updated_time", userInfo.getModifiedDate()); + jwtClaimsSetBuilder.claim("birthdate", userInfo.getBirthDate()); + } + + if(scopes.contains("email")){ + jwtClaimsSetBuilder.claim("email", userInfo.getWorkEmail()); + jwtClaimsSetBuilder.claim("email_verified", false); + } + + if(scopes.contains("phone")){ + jwtClaimsSetBuilder.claim("phone_number", userInfo.getWorkPhoneNumber()); + jwtClaimsSetBuilder.claim("phone_number_verified", false); + } + + if(scopes.contains("address")){ + HashMap addressFields = new HashMap(); + addressFields.put("country", userInfo.getWorkCountry()); + addressFields.put("region", userInfo.getWorkRegion()); + addressFields.put("locality", userInfo.getWorkLocality()); + addressFields.put("street_address", userInfo.getWorkStreetAddress()); + addressFields.put("formatted", userInfo.getWorkAddressFormatted()); + addressFields.put("postal_code", userInfo.getWorkPostalCode()); + + jwtClaimsSetBuilder.claim("address", addressFields); + } + + jwtClaimsSetBuilder + .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)); + + 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=ReciprocalUtils.decoder(clientDetails.getClientSecret()); + + JwtSigningAndValidationService symmetricJwtSignerService =symmetricJwtSignerServiceBuilder.serviceBuilder(client_secret); + if(symmetricJwtSignerService!=null){ + userInfoJWTClaims = new JWTClaimsSet.Builder(userInfoJWTClaims).claim("kid", "SYMMETRIC-KEY").build(); + userInfoJWT = new SignedJWT(new JWSHeader(signingAlg), userInfoJWTClaims); + symmetricJwtSignerService.signJwt((SignedJWT) userInfoJWT); + }else{ + _logger.error("Couldn't create symmetric validator for client " + clientDetails.getClientId() + " without a client secret"); + } + } else { + userInfoJWTClaims = new JWTClaimsSet.Builder(userInfoJWTClaims).claim("kid", jwtSignerValidationService.getDefaultSignerKeyId()).build(); + userInfoJWT = new SignedJWT(new JWSHeader(signingAlg), userInfoJWTClaims); + // sign it with the server's key + jwtSignerValidationService.signJwt((SignedJWT) userInfoJWT); + } + userJson=userInfoJWT.serialize(); + }else { + //不需要加密和签名 + response.setContentType(ContentType.APPLICATION_JSON_UTF8); + // unsigned ID token + //userInfoJWT = new PlainJWT(userInfoJWTClaims); + userJson=JsonUtils.gson2Json(jwtClaimsSetBuilder.getClaims()); + } + + return userJson; + + }catch(OAuth2Exception e){ + HashMapauthzException=new HashMap(); + authzException.put(OAuth2Exception.ERROR, e.getOAuth2ErrorCode()); + authzException.put(OAuth2Exception.DESCRIPTION,e.getMessage()); + return JsonUtils.object2Json(authzException); + } + } + + public HashMap accessTokenFormatError(String access_token){ + HashMapatfe=new HashMap(); + atfe.put(OAuth2Exception.ERROR, "token Format Invalid"); + atfe.put(OAuth2Exception.DESCRIPTION, "access Token Format Invalid , access_token : "+access_token); + + return atfe; + } + + public UserInfo queryUserInfo(String uid){ + _logger.debug("uid : "+uid); + UserInfo userInfo = (UserInfo) userInfoService.loadByUsername(uid); + return userInfo; + } + + + public void setOauth20tokenServices(DefaultTokenServices oauth20tokenServices) { + this.oauth20tokenServices = oauth20tokenServices; + } + + + + 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/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 aff288684..43d1eb7ac 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,32 +17,24 @@ package org.maxkey.authz.oauth2.provider.userinfo.endpoint; -import java.util.Arrays; -import java.util.Date; import java.util.Enumeration; import java.util.HashMap; -import java.util.Set; -import java.util.UUID; - import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - import org.maxkey.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.Boolean; -import org.maxkey.constants.ContentType; -import org.maxkey.crypto.ReciprocalUtils; import org.maxkey.crypto.jwt.encryption.service.JwtEncryptionAndDecryptionService; import org.maxkey.crypto.jwt.encryption.service.impl.RecipientJwtEncryptionAndDecryptionServiceBuilder; import org.maxkey.crypto.jwt.signer.service.JwtSigningAndValidationService; import org.maxkey.crypto.jwt.signer.service.impl.SymmetricSigningAndValidationServiceBuilder; import org.maxkey.domain.UserInfo; import org.maxkey.domain.apps.Apps; -import org.maxkey.domain.apps.oauth2.provider.ClientDetails; import org.maxkey.persistence.service.AppsService; import org.maxkey.persistence.service.UserInfoService; import org.maxkey.util.AuthorizationHeaderUtils; @@ -50,7 +42,6 @@ import org.maxkey.util.Instance; import org.maxkey.util.JsonUtils; import org.maxkey.util.StringGenerator; import org.maxkey.web.HttpResponseAdapter; -import org.maxkey.web.WebConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -59,26 +50,11 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; - -import com.nimbusds.jose.EncryptionMethod; -import com.nimbusds.jose.JWEAlgorithm; -import com.nimbusds.jose.JWEHeader; -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jose.JWSHeader; -import com.nimbusds.jwt.EncryptedJWT; -import com.nimbusds.jwt.JWT; -import com.nimbusds.jwt.JWTClaimsSet; -import com.nimbusds.jwt.JWTClaimsSet.Builder; - import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; -import com.nimbusds.jwt.SignedJWT; - @Api(tags = "2-1-OAuth v2.0 API文档模块") @Controller -@RequestMapping(value = { "/api" }) public class UserInfoEndpoint { final static Logger _logger = LoggerFactory.getLogger(UserInfoEndpoint.class); @Autowired @@ -120,7 +96,7 @@ public class UserInfoEndpoint { protected HttpResponseAdapter httpResponseAdapter; @ApiOperation(value = "OAuth 2.0 用户信息接口", notes = "传递参数access_token",httpMethod="GET") - @RequestMapping(value="/oauth/v20/me") + @RequestMapping(value=OAuth2Constants.ENDPOINT.ENDPOINT_USERINFO) public void apiV20UserInfo( @RequestParam(value = "access_token", required = false) String access_token, @RequestHeader(value = "authorization", required = false) String authorization_bearer, @@ -173,162 +149,6 @@ public class UserInfoEndpoint { } } - @ApiOperation(value = "OIDC 用户信息接口", notes = "传递Authorization参数access_token",httpMethod="GET") - @RequestMapping(value="/connect/v10/userinfo") - @ResponseBody - public String connect10aUserInfo( - @RequestHeader(value = "Authorization", required = true) String access_token, - HttpServletRequest request, - HttpServletResponse response) { - String principal=""; - if (!StringGenerator.uuidMatches(access_token)) { - return JsonUtils.gson2Json(accessTokenFormatError(access_token)); - } - - OAuth2Authentication oAuth2Authentication =null; - try{ - oAuth2Authentication = oauth20tokenServices.loadAuthentication(access_token); - - principal=((SigninPrincipal)oAuth2Authentication.getPrincipal()).getUsername(); - - Setscopes=oAuth2Authentication.getOAuth2Request().getScope(); - ClientDetails clientDetails = clientDetailsService.loadClientByClientId(oAuth2Authentication.getOAuth2Request().getClientId()); - - UserInfo userInfo=queryUserInfo(principal); - String userJson=""; - Builder jwtClaimsSetBuilder= new JWTClaimsSet.Builder(); - - SigninPrincipal authentication = (SigninPrincipal)oAuth2Authentication.getUserAuthentication().getPrincipal(); - - jwtClaimsSetBuilder.claim("sub", userInfo.getId()); - jwtClaimsSetBuilder.claim(WebConstants.ONLINE_TICKET_NAME, authentication.getOnlineTicket().getTicketId()); - - if(scopes.contains("profile")){ - jwtClaimsSetBuilder.claim("name", userInfo.getUsername()); - jwtClaimsSetBuilder.claim("preferred_username", userInfo.getDisplayName()); - jwtClaimsSetBuilder.claim("given_name", userInfo.getGivenName()); - jwtClaimsSetBuilder.claim("family_name", userInfo.getFamilyName()); - jwtClaimsSetBuilder.claim("middle_name", userInfo.getMiddleName()); - jwtClaimsSetBuilder.claim("nickname", userInfo.getNickName()); - jwtClaimsSetBuilder.claim("profile", "profile"); - jwtClaimsSetBuilder.claim("picture", "picture"); - jwtClaimsSetBuilder.claim("website", userInfo.getWebSite()); - - String gender; - switch(userInfo.getGender()){ - case UserInfo.GENDER.MALE : - gender="male";break; - case UserInfo.GENDER.FEMALE : - gender="female";break; - default: - gender="unknown"; - } - jwtClaimsSetBuilder.claim("gender", gender); - jwtClaimsSetBuilder.claim("zoneinfo", userInfo.getTimeZone()); - jwtClaimsSetBuilder.claim("locale", userInfo.getLocale()); - jwtClaimsSetBuilder.claim("updated_time", userInfo.getModifiedDate()); - jwtClaimsSetBuilder.claim("birthdate", userInfo.getBirthDate()); - } - - if(scopes.contains("email")){ - jwtClaimsSetBuilder.claim("email", userInfo.getWorkEmail()); - jwtClaimsSetBuilder.claim("email_verified", false); - } - - if(scopes.contains("phone")){ - jwtClaimsSetBuilder.claim("phone_number", userInfo.getWorkPhoneNumber()); - jwtClaimsSetBuilder.claim("phone_number_verified", false); - } - - if(scopes.contains("address")){ - HashMap addressFields = new HashMap(); - addressFields.put("country", userInfo.getWorkCountry()); - addressFields.put("region", userInfo.getWorkRegion()); - addressFields.put("locality", userInfo.getWorkLocality()); - addressFields.put("street_address", userInfo.getWorkStreetAddress()); - addressFields.put("formatted", userInfo.getWorkAddressFormatted()); - addressFields.put("postal_code", userInfo.getWorkPostalCode()); - - jwtClaimsSetBuilder.claim("address", addressFields); - } - - jwtClaimsSetBuilder - .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)); - - 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=ReciprocalUtils.decoder(clientDetails.getClientSecret()); - - JwtSigningAndValidationService symmetricJwtSignerService =symmetricJwtSignerServiceBuilder.serviceBuilder(client_secret); - if(symmetricJwtSignerService!=null){ - userInfoJWTClaims = new JWTClaimsSet.Builder(userInfoJWTClaims).claim("kid", "SYMMETRIC-KEY").build(); - userInfoJWT = new SignedJWT(new JWSHeader(signingAlg), userInfoJWTClaims); - symmetricJwtSignerService.signJwt((SignedJWT) userInfoJWT); - }else{ - _logger.error("Couldn't create symmetric validator for client " + clientDetails.getClientId() + " without a client secret"); - } - } else { - userInfoJWTClaims = new JWTClaimsSet.Builder(userInfoJWTClaims).claim("kid", jwtSignerValidationService.getDefaultSignerKeyId()).build(); - userInfoJWT = new SignedJWT(new JWSHeader(signingAlg), userInfoJWTClaims); - // sign it with the server's key - jwtSignerValidationService.signJwt((SignedJWT) userInfoJWT); - } - userJson=userInfoJWT.serialize(); - }else { - //不需要加密和签名 - response.setContentType(ContentType.APPLICATION_JSON_UTF8); - // unsigned ID token - //userInfoJWT = new PlainJWT(userInfoJWTClaims); - userJson=JsonUtils.gson2Json(jwtClaimsSetBuilder.getClaims()); - } - - return userJson; - - }catch(OAuth2Exception e){ - HashMapauthzException=new HashMap(); - authzException.put(OAuth2Exception.ERROR, e.getOAuth2ErrorCode()); - authzException.put(OAuth2Exception.DESCRIPTION,e.getMessage()); - return JsonUtils.object2Json(authzException); - } - } - public HashMap accessTokenFormatError(String access_token){ HashMapatfe=new HashMap(); atfe.put(OAuth2Exception.ERROR, "token Format Invalid"); 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 53fde7b51..b48037564 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 @@ -24,6 +24,7 @@ import java.security.spec.InvalidKeySpecException; import javax.servlet.Filter; import javax.sql.DataSource; import org.maxkey.authn.support.jwt.JwtLoginService; +import org.maxkey.authz.oauth2.common.OAuth2Constants; import org.maxkey.authz.oauth2.provider.ClientDetailsService; import org.maxkey.authz.oauth2.provider.OAuth2UserDetailsService; import org.maxkey.authz.oauth2.provider.approval.TokenApprovalStore; @@ -79,7 +80,7 @@ public class Oauth20AutoConfiguration implements InitializingBean { _logger.debug("TokenEndpointAuthenticationFilter init "); FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setFilter(new TokenEndpointAuthenticationFilter()); - registration.addUrlPatterns("/oauth/v20/token/*"); + registration.addUrlPatterns(OAuth2Constants.ENDPOINT.ENDPOINT_TOKEN + "/*"); registration.setName("TokenEndpointAuthenticationFilter"); registration.setOrder(1); return registration; diff --git a/maxkey-web-manage/src/main/resources/application.properties b/maxkey-web-manage/src/main/resources/application.properties index 27f57065e..6765f293d 100644 --- a/maxkey-web-manage/src/main/resources/application.properties +++ b/maxkey-web-manage/src/main/resources/application.properties @@ -212,8 +212,8 @@ maxkey.saml.v20.sp.issuing.entity.id=client.maxkey.org #OIDC V1.0 METADATA configuration # ############################################################################# maxkey.oidc.metadata.issuer=https://${maxkey.server.domain}/maxkey -maxkey.oidc.metadata.authorizationEndpoint=${maxkey.server.name}/maxkey/oauth/v20/authorize -maxkey.oidc.metadata.tokenEndpoint=${maxkey.server.name}/maxkey/oauth/v20/token +maxkey.oidc.metadata.authorizationEndpoint=${maxkey.server.name}/maxkey/authz/oauth/v20/authorize +maxkey.oidc.metadata.tokenEndpoint=${maxkey.server.name}/maxkey/authz/oauth/v20/token maxkey.oidc.metadata.userinfoEndpoint=${maxkey.server.name}/maxkey/api/connect/userinfo ############################################################################# diff --git a/maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyMvcConfig.java b/maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyMvcConfig.java index f716f11a5..f2a3dcb9a 100644 --- a/maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyMvcConfig.java +++ b/maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyMvcConfig.java @@ -180,8 +180,8 @@ public class MaxKeyMvcConfig implements WebMvcConfigurer { .excludePathPatterns("/authz/cas/v1/tickets/*") //OAuth - .addPathPatterns("/oauth/v20/authorize") - .addPathPatterns("/oauth/v20/authorize/*") + .addPathPatterns("/authz/oauth/v20/authorize") + .addPathPatterns("/authz/oauth/v20/authorize/*") //online ticket Validate .excludePathPatterns("/onlineticket/ticketValidate") diff --git a/maxkey-web-maxkey/src/main/resources/application-http.properties b/maxkey-web-maxkey/src/main/resources/application-http.properties index 022a336c1..d9e61a67e 100644 --- a/maxkey-web-maxkey/src/main/resources/application-http.properties +++ b/maxkey-web-maxkey/src/main/resources/application-http.properties @@ -287,8 +287,8 @@ maxkey.support.wsfederation.logoutUrl=https://adfs.maxkey.top/adfs/ls/?wa=wsigno #OIDC V1.0 METADATA configuration # ############################################################################# maxkey.oidc.metadata.issuer=${maxkey.server.name}/maxkey -maxkey.oidc.metadata.authorizationEndpoint=${maxkey.server.name}/maxkey/oauth/v20/authorize -maxkey.oidc.metadata.tokenEndpoint=${maxkey.server.name}/maxkey/oauth/v20/token +maxkey.oidc.metadata.authorizationEndpoint=${maxkey.server.name}/maxkey/authz/oauth/v20/authorize +maxkey.oidc.metadata.tokenEndpoint=${maxkey.server.name}/maxkey/authz/oauth/v20/token maxkey.oidc.metadata.userinfoEndpoint=${maxkey.server.name}/maxkey/api/connect/userinfo ############################################################################# diff --git a/maxkey-web-maxkey/src/main/resources/application-https.properties b/maxkey-web-maxkey/src/main/resources/application-https.properties index 42ac7e4e6..3fd44852b 100644 --- a/maxkey-web-maxkey/src/main/resources/application-https.properties +++ b/maxkey-web-maxkey/src/main/resources/application-https.properties @@ -287,8 +287,8 @@ maxkey.support.wsfederation.logoutUrl=https://adfs.maxkey.top/adfs/ls/?wa=wsigno #OIDC V1.0 METADATA configuration # ############################################################################# maxkey.oidc.metadata.issuer=${maxkey.server.name}/maxkey -maxkey.oidc.metadata.authorizationEndpoint=${maxkey.server.name}/maxkey/oauth/v20/authorize -maxkey.oidc.metadata.tokenEndpoint=${maxkey.server.name}/maxkey/oauth/v20/token +maxkey.oidc.metadata.authorizationEndpoint=${maxkey.server.name}/maxkey/authz/oauth/v20/authorize +maxkey.oidc.metadata.tokenEndpoint=${maxkey.server.name}/maxkey/authz/oauth/v20/token maxkey.oidc.metadata.userinfoEndpoint=${maxkey.server.name}/maxkey/api/connect/userinfo ############################################################################# diff --git a/maxkey-web-maxkey/src/main/resources/static/trusts/openid-configuration b/maxkey-web-maxkey/src/main/resources/static/trusts/openid-configuration index 04785993b..c2e690ae7 100644 --- a/maxkey-web-maxkey/src/main/resources/static/trusts/openid-configuration +++ b/maxkey-web-maxkey/src/main/resources/static/trusts/openid-configuration @@ -1,10 +1,10 @@ { - "issuer": "http://login.connsec.com", - "authorization_endpoint": "http://login.connsec.com/sec/oauth/v20/authorize", - "token_endpoint": "http://login.connsec.com/sec/oauth/v20/token", - "userinfo_endpoint": "http://login.connsec.com/sec/api/connect/v10/userinfo", + "issuer": "http://sso.maxkey.top", + "authorization_endpoint": "http://sso.maxkey.top/maxkey/authz/oauth/v20/authorize", + "token_endpoint": "http://sso.maxkey.top/maxkey/authz/oauth/v20/token", + "userinfo_endpoint": "http://sso.maxkey.top/maxkey/api/connect/v10/userinfo", "revocation_endpoint": "", - "jwks_uri": "http://login.connsec.com/sec/key/jwk", + "jwks_uri": "http://sso.maxkey.top/maxkey/key/jwk", "display_values_supported": [ "page", "popup", diff --git a/maxkey-web-maxkey/src/main/resources/templates/views/authorize/oauth_access_confirmation.ftl b/maxkey-web-maxkey/src/main/resources/templates/views/authorize/oauth_access_confirmation.ftl index fab138610..3f29906f3 100644 --- a/maxkey-web-maxkey/src/main/resources/templates/views/authorize/oauth_access_confirmation.ftl +++ b/maxkey-web-maxkey/src/main/resources/templates/views/authorize/oauth_access_confirmation.ftl @@ -40,7 +40,7 @@ -
+