From e2071a291ce77179e3d57ca56199cc07c905c739 Mon Sep 17 00:00:00 2001 From: shimingxy Date: Thu, 25 Jun 2020 10:13:00 +0800 Subject: [PATCH] Rest Api for Orgs and Users Rest Api for Orgs and Users --- .../autoconfigure/MvcAutoConfiguration.java | 10 +- .../maxkey/util/AuthorizationHeaderUtils.java | 98 +++++++++---------- .../kafka/KafkaProvisioningService.java | 28 +++++- .../maxkey-identity-rest/.classpath | 36 +++++++ .../maxkey-identity-rest/.project | 41 ++++++++ .../org.eclipse.buildship.core.prefs | 2 + .../org.eclipse.core.resources.prefs | 2 + .../org.eclipse.wst.common.component | 16 +++ ....eclipse.wst.common.project.facet.core.xml | 6 ++ .../org.springframework.ide.eclipse.prefs | 2 + .../maxkey-identity-rest/build.gradle | 15 +++ .../identity/rest/RestApiOrgController.java | 70 +++++++++++++ .../rest/RestApiUserInfoController.java | 74 ++++++++++++++ maxkey-web-manage/build.gradle | 1 + .../java/org/maxkey/MaxKeyMgtApplication.java | 3 +- .../main/java/org/maxkey/MaxKeyMgtConfig.java | 47 +++++++++ .../java/org/maxkey/MaxKeyMgtMvcConfig.java | 11 +++ .../Oauth20ApiPermissionAdapter.java | 64 ++++++++++++ .../interceptor/RestApiPermissionAdapter.java | 67 +++++++++++++ settings.gradle | 1 + 20 files changed, 537 insertions(+), 57 deletions(-) create mode 100644 maxkey-identitys/maxkey-identity-rest/.classpath create mode 100644 maxkey-identitys/maxkey-identity-rest/.project create mode 100644 maxkey-identitys/maxkey-identity-rest/.settings/org.eclipse.buildship.core.prefs create mode 100644 maxkey-identitys/maxkey-identity-rest/.settings/org.eclipse.core.resources.prefs create mode 100644 maxkey-identitys/maxkey-identity-rest/.settings/org.eclipse.wst.common.component create mode 100644 maxkey-identitys/maxkey-identity-rest/.settings/org.eclipse.wst.common.project.facet.core.xml create mode 100644 maxkey-identitys/maxkey-identity-rest/.settings/org.springframework.ide.eclipse.prefs create mode 100644 maxkey-identitys/maxkey-identity-rest/build.gradle create mode 100644 maxkey-identitys/maxkey-identity-rest/src/main/java/org/maxkey/identity/rest/RestApiOrgController.java create mode 100644 maxkey-identitys/maxkey-identity-rest/src/main/java/org/maxkey/identity/rest/RestApiUserInfoController.java create mode 100644 maxkey-web-manage/src/main/java/org/maxkey/web/interceptor/Oauth20ApiPermissionAdapter.java create mode 100644 maxkey-web-manage/src/main/java/org/maxkey/web/interceptor/RestApiPermissionAdapter.java diff --git a/maxkey-core/src/main/java/org/maxkey/autoconfigure/MvcAutoConfiguration.java b/maxkey-core/src/main/java/org/maxkey/autoconfigure/MvcAutoConfiguration.java index 38bc50fb3..c028c771d 100644 --- a/maxkey-core/src/main/java/org/maxkey/autoconfigure/MvcAutoConfiguration.java +++ b/maxkey-core/src/main/java/org/maxkey/autoconfigure/MvcAutoConfiguration.java @@ -3,7 +3,6 @@ package org.maxkey.autoconfigure; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; - import org.maxkey.constants.ConstantsProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -134,6 +133,8 @@ public class MvcAutoConfiguration implements InitializingBean { marshallingHttpMessageConverter.setUnmarshaller(jaxb2Marshaller); ArrayList mediaTypesList = new ArrayList(); mediaTypesList.add(MediaType.APPLICATION_XML); + mediaTypesList.add(MediaType.TEXT_XML); + mediaTypesList.add(MediaType.TEXT_PLAIN); marshallingHttpMessageConverter.setSupportedMediaTypes(mediaTypesList); return marshallingHttpMessageConverter; } @@ -148,6 +149,7 @@ public class MvcAutoConfiguration implements InitializingBean { new MappingJackson2HttpMessageConverter(); ArrayList mediaTypesList = new ArrayList(); mediaTypesList.add(MediaType.APPLICATION_JSON); + mediaTypesList.add(MediaType.TEXT_PLAIN); mappingJacksonHttpMessageConverter.setSupportedMediaTypes(mediaTypesList); return mappingJacksonHttpMessageConverter; } @@ -173,14 +175,14 @@ public class MvcAutoConfiguration implements InitializingBean { MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter, MarshallingHttpMessageConverter marshallingHttpMessageConverter, StringHttpMessageConverter stringHttpMessageConverter) { - - RequestMappingHandlerAdapter requestMappingHandlerAdapter = - new RequestMappingHandlerAdapter(); List> httpMessageConverterList = new ArrayList>(); httpMessageConverterList.add(mappingJacksonHttpMessageConverter); httpMessageConverterList.add(marshallingHttpMessageConverter); httpMessageConverterList.add(stringHttpMessageConverter); + + RequestMappingHandlerAdapter requestMappingHandlerAdapter = + new RequestMappingHandlerAdapter(); requestMappingHandlerAdapter.setMessageConverters(httpMessageConverterList); return requestMappingHandlerAdapter; } diff --git a/maxkey-core/src/main/java/org/maxkey/util/AuthorizationHeaderUtils.java b/maxkey-core/src/main/java/org/maxkey/util/AuthorizationHeaderUtils.java index 3a52ae0f0..512af6adc 100644 --- a/maxkey-core/src/main/java/org/maxkey/util/AuthorizationHeaderUtils.java +++ b/maxkey-core/src/main/java/org/maxkey/util/AuthorizationHeaderUtils.java @@ -7,59 +7,55 @@ import org.maxkey.crypto.Base64Utils; * */ public class AuthorizationHeaderUtils { - - public static String AUTHORIZATION_HEADERNAME="Authorization"; - - public static String BASIC="Basic "; - - public static String BEARER="Bearer "; - public static String createBasic( String username, String password ){ - String authUserPass = username + ":" + password; - String encodedAuthUserPass = Base64Utils.encode(authUserPass ); - return BASIC + encodedAuthUserPass; - } + public static final String AUTHORIZATION_HEADERNAME = "Authorization"; - public static String [] resolveBasic( String basic ){ - if(isBasic(basic)){ - String[] userPass =basic.split(" "); - String decodeUserPass = Base64Utils.decode(userPass[1] ); - return decodeUserPass.split(":"); - }else{ - return null; - } - } - - public static boolean isBasic( String basic ){ - if(basic.startsWith(BASIC )){ - return true; - }else{ - return false; - } - } - - public static String resolveBearer( String bearer ){ - if(isBearer(bearer)){ - return bearer.split(" ")[1]; - }else{ - return null; - } - } - - - public static String createBearer(String bearer){ - return BEARER +bearer; - } - + public static final String BASIC = "Basic "; - - public static boolean isBearer( String bearer ){ - if(bearer.startsWith(BEARER )){ - return true; - }else{ - return false; - } - } + public static final String BEARER = "Bearer "; + + public static String createBasic(String username, String password) { + String authUserPass = username + ":" + password; + String encodedAuthUserPass = Base64Utils.encode(authUserPass); + return BASIC + encodedAuthUserPass; + } + + public static String[] resolveBasic(String basic) { + if (isBasic(basic)) { + String[] userPass = basic.split(" "); + String decodeUserPass = Base64Utils.decode(userPass[1]); + return decodeUserPass.split(":"); + } else { + return null; + } + } + + public static boolean isBasic(String basic) { + if (basic.startsWith(BASIC)) { + return true; + } else { + return false; + } + } + + public static String resolveBearer(String bearer) { + if (isBearer(bearer)) { + return bearer.split(" ")[1]; + } else { + return null; + } + } + + public static String createBearer(String bearer) { + return BEARER + bearer; + } + + public static boolean isBearer(String bearer) { + if (bearer.startsWith(BEARER)) { + return true; + } else { + return false; + } + } - } diff --git a/maxkey-identitys/maxkey-identity-kafka/src/main/java/org/maxkey/identity/kafka/KafkaProvisioningService.java b/maxkey-identitys/maxkey-identity-kafka/src/main/java/org/maxkey/identity/kafka/KafkaProvisioningService.java index f6bc66622..89b8ddecc 100644 --- a/maxkey-identitys/maxkey-identity-kafka/src/main/java/org/maxkey/identity/kafka/KafkaProvisioningService.java +++ b/maxkey-identitys/maxkey-identity-kafka/src/main/java/org/maxkey/identity/kafka/KafkaProvisioningService.java @@ -40,9 +40,35 @@ public class KafkaProvisioningService { message.setContent(JsonUtils.gson2Json(content)); String msg = JsonUtils.gson2Json(message); _logger.info("send message = {}", msg); + //通过线程发送Kafka消息 + KafkaProvisioningThread thread = + new KafkaProvisioningThread(kafkaTemplate,topic,msg); - kafkaTemplate.send(topic, msg); + thread.start(); } } + + + class KafkaProvisioningThread extends Thread{ + + KafkaTemplate kafkaTemplate; + + String topic ; + + String msg; + + public KafkaProvisioningThread(KafkaTemplate kafkaTemplate, String topic, String msg) { + this.kafkaTemplate = kafkaTemplate; + this.topic = topic; + this.msg = msg; + } + + @Override + public void run() { + kafkaTemplate.send(topic, msg); + } + + } + } diff --git a/maxkey-identitys/maxkey-identity-rest/.classpath b/maxkey-identitys/maxkey-identity-rest/.classpath new file mode 100644 index 000000000..eca1d9e92 --- /dev/null +++ b/maxkey-identitys/maxkey-identity-rest/.classpath @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/maxkey-identitys/maxkey-identity-rest/.project b/maxkey-identitys/maxkey-identity-rest/.project new file mode 100644 index 000000000..2de411109 --- /dev/null +++ b/maxkey-identitys/maxkey-identity-rest/.project @@ -0,0 +1,41 @@ + + + maxkey-identity-rest + Project maxkey-identity-rest created by Buildship. + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + org.springframework.ide.eclipse.boot.validation.springbootbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/maxkey-identitys/maxkey-identity-rest/.settings/org.eclipse.buildship.core.prefs b/maxkey-identitys/maxkey-identity-rest/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 000000000..62e3e7e80 --- /dev/null +++ b/maxkey-identitys/maxkey-identity-rest/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir=../.. +eclipse.preferences.version=1 diff --git a/maxkey-identitys/maxkey-identity-rest/.settings/org.eclipse.core.resources.prefs b/maxkey-identitys/maxkey-identity-rest/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 000000000..896a9a53a --- /dev/null +++ b/maxkey-identitys/maxkey-identity-rest/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 \ No newline at end of file diff --git a/maxkey-identitys/maxkey-identity-rest/.settings/org.eclipse.wst.common.component b/maxkey-identitys/maxkey-identity-rest/.settings/org.eclipse.wst.common.component new file mode 100644 index 000000000..ab948f2be --- /dev/null +++ b/maxkey-identitys/maxkey-identity-rest/.settings/org.eclipse.wst.common.component @@ -0,0 +1,16 @@ + + + + + + + uses + + + uses + + + uses + + + diff --git a/maxkey-identitys/maxkey-identity-rest/.settings/org.eclipse.wst.common.project.facet.core.xml b/maxkey-identitys/maxkey-identity-rest/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..509bad92c --- /dev/null +++ b/maxkey-identitys/maxkey-identity-rest/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/maxkey-identitys/maxkey-identity-rest/.settings/org.springframework.ide.eclipse.prefs b/maxkey-identitys/maxkey-identity-rest/.settings/org.springframework.ide.eclipse.prefs new file mode 100644 index 000000000..a12794d68 --- /dev/null +++ b/maxkey-identitys/maxkey-identity-rest/.settings/org.springframework.ide.eclipse.prefs @@ -0,0 +1,2 @@ +boot.validation.initialized=true +eclipse.preferences.version=1 diff --git a/maxkey-identitys/maxkey-identity-rest/build.gradle b/maxkey-identitys/maxkey-identity-rest/build.gradle new file mode 100644 index 000000000..95861151c --- /dev/null +++ b/maxkey-identitys/maxkey-identity-rest/build.gradle @@ -0,0 +1,15 @@ +description = "maxkey-identity-rest" + +apply plugin: 'java' +apply plugin: 'eclipse-wtp' + + +dependencies { + //local jars + compile fileTree(dir: '../maxkey-lib/*/', include: '*.jar') + + compile project(":maxkey-core") + compile project(":maxkey-dao") + compile project(":maxkey-client-sdk") + +} \ No newline at end of file diff --git a/maxkey-identitys/maxkey-identity-rest/src/main/java/org/maxkey/identity/rest/RestApiOrgController.java b/maxkey-identitys/maxkey-identity-rest/src/main/java/org/maxkey/identity/rest/RestApiOrgController.java new file mode 100644 index 000000000..897ced9d9 --- /dev/null +++ b/maxkey-identitys/maxkey-identity-rest/src/main/java/org/maxkey/identity/rest/RestApiOrgController.java @@ -0,0 +1,70 @@ +package org.maxkey.identity.rest; + +import java.io.IOException; + +import org.maxkey.dao.service.OrganizationsService; +import org.maxkey.domain.Organizations; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.util.UriComponentsBuilder; + +@Controller +@RequestMapping(value={"/identity/api/org"}) +public class RestApiOrgController { + + @Autowired + OrganizationsService organizationsService; + + @ResponseBody + @RequestMapping(value = "/{id}", method = RequestMethod.GET) + public Organizations getUser(@PathVariable String id, + @RequestParam(required = false) String attributes) { + Organizations org = organizationsService.get(id); + return org; + } + + @ResponseBody + @RequestMapping(method = RequestMethod.POST) + public Organizations create(@RequestBody Organizations org, + @RequestParam(required = false) String attributes, + UriComponentsBuilder builder) throws IOException { + Organizations loadOrg = organizationsService.get(org.getId()); + if(loadOrg == null) { + organizationsService.insert(org); + }else { + organizationsService.update(org); + } + return org; + } + + @ResponseBody + @RequestMapping(value = "/{id}", method = RequestMethod.PUT) + public Organizations replace(@PathVariable String id, + @RequestBody Organizations org, + @RequestParam(required = false) String attributes) + throws IOException { + Organizations loadOrg = organizationsService.get(id); + if(loadOrg == null) { + organizationsService.insert(org); + }else { + organizationsService.update(org); + } + + return org; + } + + @RequestMapping(value = "/{id}", method = RequestMethod.DELETE) + @ResponseStatus(HttpStatus.OK) + public void delete(@PathVariable final String id) { + organizationsService.remove(id); + + } +} diff --git a/maxkey-identitys/maxkey-identity-rest/src/main/java/org/maxkey/identity/rest/RestApiUserInfoController.java b/maxkey-identitys/maxkey-identity-rest/src/main/java/org/maxkey/identity/rest/RestApiUserInfoController.java new file mode 100644 index 000000000..1c58eb1ed --- /dev/null +++ b/maxkey-identitys/maxkey-identity-rest/src/main/java/org/maxkey/identity/rest/RestApiUserInfoController.java @@ -0,0 +1,74 @@ +package org.maxkey.identity.rest; + +import java.io.IOException; + +import org.maxkey.dao.service.UserInfoService; +import org.maxkey.domain.UserInfo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.util.UriComponentsBuilder; + +@Controller +@RequestMapping(value={"/identity/api/userinfo"}) +public class RestApiUserInfoController { + + @Autowired + @Qualifier("userInfoService") + private UserInfoService userInfoService; + + @RequestMapping(value = "/{id}", method = RequestMethod.GET) + @ResponseBody + public UserInfo getUser( + @PathVariable String id, + @RequestParam(required = false) String attributes) { + + UserInfo loadUserInfo = userInfoService.get(id); + loadUserInfo.setDecipherable(null); + return loadUserInfo; + } + + @RequestMapping(method = RequestMethod.POST) + @ResponseBody + public UserInfo create(@RequestBody UserInfo userInfo, + @RequestParam(required = false) String attributes, + UriComponentsBuilder builder) throws IOException { + UserInfo loadUserInfo = userInfoService.loadByUsername(userInfo.getUsername()); + if(loadUserInfo != null) { + userInfoService.update(userInfo); + }else { + userInfoService.insert(userInfo); + } + return userInfo; + } + + @RequestMapping(value = "/{id}", method = RequestMethod.PUT) + @ResponseBody + public UserInfo replace(@PathVariable String id, + @RequestBody UserInfo userInfo, + @RequestParam(required = false) String attributes) + throws IOException { + UserInfo loadUserInfo = userInfoService.loadByUsername(userInfo.getUsername()); + if(loadUserInfo != null) { + userInfoService.update(userInfo); + }else { + userInfoService.insert(userInfo); + } + return userInfo; + } + + @RequestMapping(value = "/{id}", method = RequestMethod.DELETE) + @ResponseStatus(HttpStatus.OK) + public void delete(@PathVariable final String id) { + userInfoService.logisticDeleteAllByCid(id); + + } +} diff --git a/maxkey-web-manage/build.gradle b/maxkey-web-manage/build.gradle index f52525c45..6b5bb46bf 100644 --- a/maxkey-web-manage/build.gradle +++ b/maxkey-web-manage/build.gradle @@ -24,6 +24,7 @@ dependencies { compile project(":maxkey-protocols:maxkey-protocol-saml-2.0") compile project(":maxkey-identitys:maxkey-identity-scim") compile project(":maxkey-identitys:maxkey-identity-kafka") + compile project(":maxkey-identitys:maxkey-identity-rest") } diff --git a/maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtApplication.java b/maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtApplication.java index 76f074a94..563576ea0 100644 --- a/maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtApplication.java +++ b/maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtApplication.java @@ -35,7 +35,8 @@ import org.springframework.context.annotation.ImportResource; "org.maxkey.web", "org.maxkey.web.tag", "org.maxkey.identity.kafka", - "org.maxkey.identity.scim.controller" + "org.maxkey.identity.scim.controller", + "org.maxkey.identity.rest" }) @MapperScan("org.maxkey.dao.persistence,") public class MaxKeyMgtApplication extends SpringBootServletInitializer { diff --git a/maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtConfig.java b/maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtConfig.java index 4530dec96..5643f1c84 100644 --- a/maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtConfig.java +++ b/maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtConfig.java @@ -2,8 +2,15 @@ package org.maxkey; import javax.sql.DataSource; import org.maxkey.authz.oauth2.provider.client.JdbcClientDetailsService; +import org.maxkey.authz.oauth2.provider.token.DefaultTokenServices; +import org.maxkey.authz.oauth2.provider.token.TokenStore; +import org.maxkey.authz.oauth2.provider.token.store.InMemoryTokenStore; +import org.maxkey.authz.oauth2.provider.token.store.JdbcTokenStore; +import org.maxkey.authz.oauth2.provider.token.store.RedisTokenStore; +import org.maxkey.authz.oidc.idtoken.OIDCIdTokenEnhancer; import org.maxkey.constants.ConstantsProperties; import org.maxkey.crypto.password.opt.impl.TimeBasedOtpAuthn; +import org.maxkey.persistence.redis.RedisConnectionFactory; import org.maxkey.authn.realm.jdbc.JdbcAuthenticationRealm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,6 +38,46 @@ public class MaxKeyMgtConfig implements InitializingBean { return clientDetailsService; } + /** + * TokenStore. + * @param persistence int + * @return oauth20TokenStore + */ + @Bean(name = "oauth20TokenStore") + public TokenStore oauth20TokenStore( + @Value("${config.server.persistence}") int persistence, + JdbcTemplate jdbcTemplate, + RedisConnectionFactory jedisConnectionFactory) { + TokenStore tokenStore = null; + if (persistence == 0) { + tokenStore = new InMemoryTokenStore(); + _logger.debug("InMemoryTokenStore"); + } else if (persistence == 1) { + tokenStore = new JdbcTokenStore(jdbcTemplate); + _logger.debug("JdbcTokenStore"); + } else if (persistence == 2) { + tokenStore = new RedisTokenStore(jedisConnectionFactory); + _logger.debug("RedisTokenStore"); + } + return tokenStore; + } + + /** + * clientDetailsUserDetailsService. + * @return oauth20TokenServices + */ + @Bean(name = "oauth20TokenServices") + public DefaultTokenServices DefaultTokenServices( + JdbcClientDetailsService oauth20JdbcClientDetailsService, + TokenStore oauth20TokenStore) { + DefaultTokenServices tokenServices = new DefaultTokenServices(); + tokenServices.setClientDetailsService(oauth20JdbcClientDetailsService); + tokenServices.setTokenStore(oauth20TokenStore); + tokenServices.setSupportRefreshToken(true); + return tokenServices; + } + + //以下内容可以注释掉后再xml中配置,xml引入在MaxKeyMgtApplication中 @Bean(name = "authenticationRealm") public JdbcAuthenticationRealm JdbcAuthenticationRealm( diff --git a/maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtMvcConfig.java b/maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtMvcConfig.java index 77615cc24..2be69631b 100644 --- a/maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtMvcConfig.java +++ b/maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtMvcConfig.java @@ -2,6 +2,7 @@ package org.maxkey; import org.maxkey.web.interceptor.HistoryLogsAdapter; import org.maxkey.web.interceptor.PermissionAdapter; +import org.maxkey.web.interceptor.RestApiPermissionAdapter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -25,6 +26,9 @@ public class MaxKeyMgtMvcConfig implements WebMvcConfigurer { @Autowired LocaleChangeInterceptor localeChangeInterceptor; + @Autowired + RestApiPermissionAdapter restApiPermissionAdapter; + @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**") @@ -73,6 +77,13 @@ public class MaxKeyMgtMvcConfig implements WebMvcConfigurer { registry.addInterceptor(localeChangeInterceptor); _logger.debug("add LocaleChangeInterceptor"); + + registry.addInterceptor(restApiPermissionAdapter) + .addPathPatterns("/identity/api/**") + ; + + _logger.debug("add RestApiPermissionAdapter"); + } } diff --git a/maxkey-web-manage/src/main/java/org/maxkey/web/interceptor/Oauth20ApiPermissionAdapter.java b/maxkey-web-manage/src/main/java/org/maxkey/web/interceptor/Oauth20ApiPermissionAdapter.java new file mode 100644 index 000000000..0684c1b7f --- /dev/null +++ b/maxkey-web-manage/src/main/java/org/maxkey/web/interceptor/Oauth20ApiPermissionAdapter.java @@ -0,0 +1,64 @@ +package org.maxkey.web.interceptor; + +import java.util.concurrent.ConcurrentHashMap; + +import javax.servlet.RequestDispatcher; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.maxkey.authz.oauth2.provider.OAuth2Authentication; +import org.maxkey.authz.oauth2.provider.token.DefaultTokenServices; +import org.maxkey.crypto.password.PasswordReciprocal; +import org.maxkey.util.AuthorizationHeaderUtils; +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.Component; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +/** + * OAuth v2.0 accessToken认证Interceptor处理. + * @author Crystal.Sea + * + */ +@Component +public class Oauth20ApiPermissionAdapter extends HandlerInterceptorAdapter { + private static final Logger _logger = LoggerFactory.getLogger(Oauth20ApiPermissionAdapter.class); + + @Autowired + @Qualifier("passwordReciprocal") + protected PasswordReciprocal passwordReciprocal; + + @Autowired + @Qualifier("oauth20TokenServices") + private DefaultTokenServices oauth20tokenServices; + + static ConcurrentHashMapnavigationsMap=null; + + /* + * 请求前处理 + * (non-Javadoc) + * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#preHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object) + */ + @Override + public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception { + _logger.trace("Oauth20ApiPermissionAdapter preHandle"); + String authorization = request.getHeader(AuthorizationHeaderUtils.AUTHORIZATION_HEADERNAME); + + String accessToken = AuthorizationHeaderUtils.resolveBearer(authorization); + OAuth2Authentication authentication = oauth20tokenServices.loadAuthentication(accessToken); + + //判断应用的accessToken信息 + if(authentication != null ){ + _logger.trace("authentication "+ authentication); + return true; + } + + _logger.trace("No Authentication ... forward to /login"); + RequestDispatcher dispatcher = request.getRequestDispatcher("/login"); + dispatcher.forward(request, response); + + return false; + } +} diff --git a/maxkey-web-manage/src/main/java/org/maxkey/web/interceptor/RestApiPermissionAdapter.java b/maxkey-web-manage/src/main/java/org/maxkey/web/interceptor/RestApiPermissionAdapter.java new file mode 100644 index 000000000..ce05ecb34 --- /dev/null +++ b/maxkey-web-manage/src/main/java/org/maxkey/web/interceptor/RestApiPermissionAdapter.java @@ -0,0 +1,67 @@ +package org.maxkey.web.interceptor; + +import java.util.concurrent.ConcurrentHashMap; + +import javax.servlet.RequestDispatcher; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.maxkey.crypto.password.PasswordReciprocal; +import org.maxkey.dao.service.AppsService; +import org.maxkey.domain.apps.Apps; +import org.maxkey.util.AuthorizationHeaderUtils; +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.Component; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +/** + * basic认证Interceptor处理. + * @author Crystal.Sea + * + */ +@Component +public class RestApiPermissionAdapter extends HandlerInterceptorAdapter { + private static final Logger _logger = LoggerFactory.getLogger(RestApiPermissionAdapter.class); + + @Autowired + AppsService appsService; + + @Autowired + @Qualifier("passwordReciprocal") + protected PasswordReciprocal passwordReciprocal; + + static ConcurrentHashMapnavigationsMap=null; + + /* + * 请求前处理 + * (non-Javadoc) + * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#preHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object) + */ + @Override + public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception { + _logger.trace("RestApiPermissionAdapter preHandle"); + String authorization = request.getHeader(AuthorizationHeaderUtils.AUTHORIZATION_HEADERNAME); + + String [] basicUserPass = AuthorizationHeaderUtils.resolveBasic(authorization); + + //判断应用的AppId和Secret + if(basicUserPass != null && basicUserPass.length==2){ + _logger.trace(""+ basicUserPass[0]+":"+basicUserPass[1]); + Apps app = appsService.get(basicUserPass[0]); + + _logger.debug("App Info "+ app.getSecret()); + if(app != null && passwordReciprocal.encode(basicUserPass[1]).equalsIgnoreCase(app.getSecret())) { + return true; + } + } + + + _logger.trace("No Authentication ... forward to /login"); + RequestDispatcher dispatcher = request.getRequestDispatcher("/login"); + dispatcher.forward(request, response); + + return false; + } +} diff --git a/settings.gradle b/settings.gradle index 0eae691ec..3d315b3c2 100644 --- a/settings.gradle +++ b/settings.gradle @@ -12,6 +12,7 @@ include 'maxkey-authentications' //identity include 'maxkey-identitys:maxkey-identity-scim' include 'maxkey-identitys:maxkey-identity-kafka' +include 'maxkey-identitys:maxkey-identity-rest' //connectors