diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/dromara/maxkey/authz/oauth2/provider/endpoint/OauthJwksEndpoint.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/dromara/maxkey/authz/oauth2/provider/endpoint/OauthJwksEndpoint.java index 18758c94d..1bc169383 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/dromara/maxkey/authz/oauth2/provider/endpoint/OauthJwksEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/dromara/maxkey/authz/oauth2/provider/endpoint/OauthJwksEndpoint.java @@ -38,34 +38,46 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; - @Tag(name = "2-1-OAuth v2.0 API文档模块") @Controller public class OauthJwksEndpoint extends AbstractEndpoint { static final Logger _logger = LoggerFactory.getLogger(OauthJwksEndpoint.class); - @Operation(summary = "OAuth JWk 元数据接口", description = "参数mxk_metadata_APPID",method="GET") - @RequestMapping( - value = OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/jwks", - method={RequestMethod.POST, RequestMethod.GET}) + @Operation(summary = "OAuth JWk 元数据接口", description = "参数inst_id , client_id",method="GET") + @RequestMapping(value = OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/jwks", + method={RequestMethod.POST, RequestMethod.GET}) @ResponseBody - public void keysMetadata(HttpServletRequest request , HttpServletResponse response, - @RequestParam(value = "client_id", required = false) String client_id) throws IOException { - metadata(request,response,client_id,null); + public String keysMetadataByParam(HttpServletRequest request , HttpServletResponse response, + @RequestParam(required = false) String inst_id, + @RequestParam(required = false) String client_id) { + return buildMetadata(request,response,inst_id,client_id,ContentType.JSON); } - @Operation(summary = "OAuth JWk 元数据接口", description = "参数mxk_metadata_APPID",method="GET") + @Operation(summary = "OAuth JWk 元数据接口", description = "参数instId , clientId",method="GET") + @RequestMapping(value = OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/{instId}/{clientId}/jwks", + method={RequestMethod.POST, RequestMethod.GET}) + @ResponseBody + public String keysMetadatabyPath(HttpServletRequest request , HttpServletResponse response, + @PathVariable String instId,@PathVariable String clientId) { + return buildMetadata(request,response,instId,clientId,ContentType.JSON); + } + + @Operation(summary = "OAuth JWk 元数据接口", description = "参数mxk_metadata_clientId",method="GET") @RequestMapping( - value = "/metadata/oauth/v20/" + WebConstants.MXK_METADATA_PREFIX + "{appid}.{mediaType}", + value = "/metadata/oauth/v20/" + WebConstants.MXK_METADATA_PREFIX + "{clientId}.{mediaType}", method={RequestMethod.POST, RequestMethod.GET}) @ResponseBody - public void metadata(HttpServletRequest request , HttpServletResponse response, - @PathVariable(value="appid", required = false) String appId, - @PathVariable(value="mediaType", required = false) String mediaType) throws IOException { + public String metadata(HttpServletRequest request , HttpServletResponse response, + @PathVariable(value="clientId", required = false) String clientId, + @PathVariable(value="mediaType", required = false) String mediaType) { + return buildMetadata(request,response,null,clientId,mediaType); + } + + public String buildMetadata(HttpServletRequest request , HttpServletResponse response, + String instId,String clientId,String mediaType){ ClientDetails clientDetails = null; try { - clientDetails = getClientDetailsService().loadClientByClientId(appId,true); + clientDetails = getClientDetailsService().loadClientByClientId(clientId,true); }catch(Exception e) { _logger.error("getClientDetailsService", e); } @@ -83,18 +95,15 @@ public class OauthJwksEndpoint extends AbstractEndpoint { } JWKSetKeyStore jwkSetKeyStore = new JWKSetKeyStore("{\"keys\": [" + jwkSetString + "]}"); - if(StringUtils.hasText(mediaType) - && mediaType.equalsIgnoreCase(ContentType.XML)) { + if(StringUtils.hasText(mediaType) && mediaType.equalsIgnoreCase(ContentType.XML)) { response.setContentType(ContentType.APPLICATION_XML_UTF8); }else { response.setContentType(ContentType.APPLICATION_JSON_UTF8); } - response.getWriter().write(jwkSetKeyStore.toString(mediaType)); + return jwkSetKeyStore.toString(mediaType); } else { - response.getWriter().write(appId + " not exist . \n" + WebContext.version()); + return clientId + " not exist . \n" + WebContext.version(); } - - } } diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/dromara/maxkey/authz/oauth2/provider/wellknown/endpoint/OauthAuthorizationServerEndpoint.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/dromara/maxkey/authz/oauth2/provider/wellknown/endpoint/OauthAuthorizationServerEndpoint.java index afaf10b09..2165fcc43 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/dromara/maxkey/authz/oauth2/provider/wellknown/endpoint/OauthAuthorizationServerEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/dromara/maxkey/authz/oauth2/provider/wellknown/endpoint/OauthAuthorizationServerEndpoint.java @@ -20,11 +20,11 @@ package org.dromara.maxkey.authz.oauth2.provider.wellknown.endpoint; import java.util.HashSet; import java.util.Set; +import org.apache.commons.lang3.StringUtils; import org.dromara.maxkey.authz.oauth2.common.OAuth2Constants; import org.dromara.maxkey.authz.oauth2.provider.endpoint.AbstractEndpoint; import org.dromara.maxkey.authz.oauth2.provider.wellknown.OauthServerConfiguration; import org.dromara.maxkey.entity.apps.oauth2.provider.ClientDetails; -import org.dromara.maxkey.pretty.impl.JsonPretty; import org.dromara.maxkey.web.WebContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,52 +35,46 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; -import com.alibaba.cloud.commons.lang.StringUtils; - import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; + @Tag(name = "2-1-OAuth v2.0 API文档模块") @Controller public class OauthAuthorizationServerEndpoint extends AbstractEndpoint { static final Logger _logger = LoggerFactory.getLogger(OauthAuthorizationServerEndpoint.class); @Operation(summary = "OAuth v2 metadata 元数据接口", description = "参数client_id",method="GET,POST") - @RequestMapping( - value = { - OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/.well-known/oauth-authorization-server"}, - produces = "application/json", - method={RequestMethod.POST, RequestMethod.GET}) + @RequestMapping(value = {OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/.well-known/oauth-authorization-server"}, + produces = "application/json", + method={RequestMethod.POST, RequestMethod.GET}) @ResponseBody - public String configuration( - HttpServletRequest request, - HttpServletResponse response, + public OauthServerConfiguration configurationByParam( + @RequestParam(value = "inst_id", required = false) String inst_id, @RequestParam(value = "client_id", required = false) String client_id) { - return configurationMetadata(request,response, null,client_id); + return configurationMetadata( inst_id,client_id,"RequestParam"); } - @Operation(summary = "OAuth v2 metadata 元数据接口", description = "参数client_id",method="GET,POST") - @RequestMapping( - value = { - OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/{instId}/.well-known/oauth-authorization-server"}, - produces = "application/json", - method={RequestMethod.POST, RequestMethod.GET}) + @Operation(summary = "OAuth v2 metadata 元数据接口", description = "参数instId,client_id",method="GET,POST") + @RequestMapping(value = {OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/{instId}/{clientId}/.well-known/oauth-authorization-server"}, + produces = "application/json", + method={RequestMethod.POST, RequestMethod.GET}) @ResponseBody - public String configurationMetadata( - HttpServletRequest request, - HttpServletResponse response, + public OauthServerConfiguration configurationByPath( @PathVariable("instId") String instId, - @RequestParam(value = "client_id", required = false) String client_id) { - _logger.debug("instId {} , client_id {}" , instId ,client_id); + @PathVariable(value = "clientId", required = false) String clientId) { + return configurationMetadata(instId,clientId,"PathVariable"); + } + + public OauthServerConfiguration configurationMetadata(String instId,String clientId,String param) { + _logger.debug("instId {} , client_id {}" , instId ,clientId); String baseUrl = WebContext.getContextPath(true); ClientDetails clientDetails = null; - if(StringUtils.isNotBlank(client_id)) { + if(StringUtils.isNotBlank(clientId)) { try { - clientDetails = getClientDetailsService().loadClientByClientId(client_id,true); + clientDetails = getClientDetailsService().loadClientByClientId(clientId,true); }catch(Exception e) { _logger.error("getClientDetailsService", e); } @@ -99,15 +93,29 @@ public class OauthAuthorizationServerEndpoint extends AbstractEndpoint { oauthConfig.setCode_challenge_methods_supported(code_challenge_methods_supported); if(clientDetails != null) { - oauthConfig.setClient_id(client_id); - oauthConfig.setJwks_uri(baseUrl + OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/jwks?client_id="+ clientDetails.getClientId()); + oauthConfig.setClient_id(clientId); + if(param.equals("RequestParam")){ + StringBuffer jwksUri = new StringBuffer(baseUrl + OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/jwks"); + jwksUri.append("?"); + jwksUri.append("client_id").append("=").append(clientDetails.getClientId()); + if(StringUtils.isNotBlank(instId)) { + jwksUri.append("&").append("inst_id").append("=").append(clientDetails.getClientId()); + } + oauthConfig.setJwks_uri(jwksUri.toString()); + }else { + oauthConfig.setJwks_uri(baseUrl + OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/"+instId+"/"+clientId+"/jwks"); + } Set introspection_endpoint_auth_methods_supported = new HashSet(); introspection_endpoint_auth_methods_supported.add("client_secret_basic"); oauthConfig.setIntrospection_endpoint_auth_methods_supported(introspection_endpoint_auth_methods_supported); oauthConfig.setIssuer(clientDetails.getIssuer()); - oauthConfig.setResponse_types_supported(clientDetails.getAuthorizedGrantTypes()); + Set response_types_supported =clientDetails.getAuthorizedGrantTypes(); + if(response_types_supported.contains("authorization_code")) { + response_types_supported.add("code"); + } + oauthConfig.setResponse_types_supported(response_types_supported); Set response_modes_supported = new HashSet(); response_modes_supported.add("query"); @@ -175,7 +183,7 @@ public class OauthAuthorizationServerEndpoint extends AbstractEndpoint { oauthConfig.setClaims_supported(claims_supported); }else { - oauthConfig.setClient_id(client_id); + oauthConfig.setClient_id(clientId); oauthConfig.setJwks_uri(baseUrl + OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/jwks"); Set introspection_endpoint_auth_methods_supported = new HashSet(); @@ -265,6 +273,6 @@ public class OauthAuthorizationServerEndpoint extends AbstractEndpoint { oauthConfig.setClaims_supported(claims_supported); } - return JsonPretty.getInstance().format(oauthConfig,true); + return oauthConfig; } } diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/dromara/maxkey/authz/oauth2/provider/wellknown/endpoint/OpenidConfigurationEndpoint.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/dromara/maxkey/authz/oauth2/provider/wellknown/endpoint/OpenidConfigurationEndpoint.java index 37fcfa005..5aa5e6294 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/dromara/maxkey/authz/oauth2/provider/wellknown/endpoint/OpenidConfigurationEndpoint.java +++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/dromara/maxkey/authz/oauth2/provider/wellknown/endpoint/OpenidConfigurationEndpoint.java @@ -20,8 +20,6 @@ package org.dromara.maxkey.authz.oauth2.provider.wellknown.endpoint; import com.alibaba.cloud.commons.lang.StringUtils; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import org.dromara.maxkey.authz.oauth2.common.OAuth2Constants; import org.dromara.maxkey.authz.oauth2.provider.endpoint.AbstractEndpoint; import org.dromara.maxkey.authz.oauth2.provider.wellknown.OpenidConfiguration; @@ -41,41 +39,40 @@ public class OpenidConfigurationEndpoint extends AbstractEndpoint { static final Logger _logger = LoggerFactory.getLogger(OpenidConfigurationEndpoint.class); - @Operation(summary = "OpenID Connect metadata 元数据接口", description = "参数client_id",method="GET,POST") - @RequestMapping( - value = { - OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/.well-known/openid-configuration"}, - produces = "application/json", - method={RequestMethod.POST, RequestMethod.GET}) + @Operation(summary = "OpenID Connect metadata 元数据接口", description = "参数inst_id,client_id",method="GET,POST") + @RequestMapping(value = {OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/.well-known/openid-configuration"}, + produces = "application/json", + method={RequestMethod.POST, RequestMethod.GET}) @ResponseBody - public OpenidConfiguration configuration( - HttpServletRequest request, - HttpServletResponse response, + public OpenidConfiguration configurationByParam( + @RequestParam(value = "inst_id", required = false) String inst_id, @RequestParam(value = "client_id", required = false) String client_id) { - return configurationMetadata(request,response, null,client_id); + _logger.debug("Configuration By Param"); + return configurationMetadata(inst_id,client_id,"RequestParam"); } - @Operation(summary = "OpenID Connect metadata 元数据接口", description = "参数client_id",method="GET,POST") - @RequestMapping( - value = { - OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/{instId}/.well-known/openid-configuration"}, - produces = "application/json", - method={RequestMethod.POST, RequestMethod.GET}) + @Operation(summary = "OpenID Connect metadata 元数据接口", description = "参数Path",method="GET,POST") + @RequestMapping(value = {OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/{instId}/{clientId}/.well-known/openid-configuration"}, + produces = "application/json", + method={RequestMethod.POST, RequestMethod.GET}) @ResponseBody - public OpenidConfiguration configurationMetadata( - HttpServletRequest request, - HttpServletResponse response, - @PathVariable("instId") String instId, - @RequestParam(value = "client_id", required = false) String client_id) { - _logger.debug("instId {} , client_id {}" , instId ,client_id); + public OpenidConfiguration configurationByPath( + @PathVariable("instId") String instId , + @PathVariable(value = "clientId") String clientId) { + _logger.debug("Configuration By Path"); + return configurationMetadata(instId,clientId,"PathVariable"); + } + + public OpenidConfiguration configurationMetadata(String instId,String clientId,String param) { + _logger.debug("instId {} , client_id {}" , instId ,clientId); String baseUrl = WebContext.getContextPath(true); ClientDetails clientDetails = null; - if(StringUtils.isNotBlank(client_id)) { + if(StringUtils.isNotBlank(clientId)) { try { - clientDetails = getClientDetailsService().loadClientByClientId(client_id,true); + clientDetails = getClientDetailsService().loadClientByClientId(clientId,true); }catch(Exception e) { _logger.error("getClientDetailsService", e); } @@ -90,8 +87,18 @@ public class OpenidConfigurationEndpoint extends AbstractEndpoint { openidConfig.setEnd_session_endpoint(baseUrl + "/force/logout"); if(clientDetails != null) { - openidConfig.setClient_id(client_id); - openidConfig.setJwks_uri(baseUrl + OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/jwks?client_id=" + clientDetails.getClientId()); + openidConfig.setClient_id(clientId); + if(param.equals("RequestParam")){ + StringBuffer jwksUri = new StringBuffer(baseUrl + OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/jwks"); + jwksUri.append("?"); + jwksUri.append("client_id").append("=").append(clientDetails.getClientId()); + if(StringUtils.isNotBlank(instId)) { + jwksUri.append("&").append("inst_id").append("=").append(clientDetails.getClientId()); + } + openidConfig.setJwks_uri(jwksUri.toString()); + }else { + openidConfig.setJwks_uri(baseUrl + OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/"+instId+"/"+clientId+"/jwks"); + } Set introspection_endpoint_auth_methods_supported = new HashSet(); introspection_endpoint_auth_methods_supported.add("client_secret_basic"); @@ -170,7 +177,7 @@ public class OpenidConfigurationEndpoint extends AbstractEndpoint { openidConfig.setClaims_supported(claims_supported); }else { - openidConfig.setClient_id(client_id); + openidConfig.setClient_id(clientId); openidConfig.setJwks_uri(baseUrl + OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/jwks"); Set introspection_endpoint_auth_methods_supported = new HashSet();