一、该问题的重现步骤是什么?
1.ApiScopePermissionHandler和BladePermissionHandler都实现了IPermissionHandler这个接口,我对ApiScopePermissionHandler进行了改造,需要怎样配置才能让接口鉴权走ApiScopePermissionHandler里面的逻辑,在哪些模块引入blade-scope-api?另外业务子系统是新建的,子系统业务使用自己独立的数据库,鉴权还是走的gateway。
启动登录时,报了sql错误。
改造的代码如下:
1.首先修改了ApiScopePermissionHandler类中的两个方法
2.ApiScopeCache中的代码也相应进行了修改,增加userPermissionCode方法
3.ApiScopeClient中的userPermissionCode方法
4.scopePermissionStatement方法,注意sql的表是另外自定义的api权限表,这个权限报在bladex数据库中
5.在blade-auth/pom.xml文件中引入blade-scope-api模块
6.启动,调用/blade-auth/oauth/token接口获取token登录时,授权模块后台报了sql错误
二、你期待的结果是什么?实际看到的又是什么?
期待结果是:对接口权限校验类进行扩展改造,使用自定义的api权限表,并对使用独立数据库的业务子系统接口进行接口鉴权。
实际情况是:改造后auth模块引入的blade-scope-api其依赖中有blade-core-secure 依赖,会与auth依赖的secure冲突,报Table 'bladex.oauth_client_details' doesn't exist,那么怎个问题怎么解决?
三、你正在使用的是什么产品,什么版本?在什么操作系统上?
saber,bladex商业版 2.7.0.REALEASE,win10
四、请提供详细的错误堆栈信息,这很重要。
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [select client_id, client_secret, resource_ids, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove from oauth_client_details where client_id = ?]; nested exception is java.sql.SQLSyntaxErrorException: Table 'bladex.oauth_client_details' doesn't exist
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:239)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1443)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:633)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:669)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:700)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:712)
at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:790)
at org.springframework.security.oauth2.provider.client.JdbcClientDetailsService.loadClientByClientId(JdbcClientDetailsService.java:119)
at org.springblade.auth.service.BladeClientDetailsServiceImpl.loadClientByClientId(BladeClientDetailsServiceImpl.java:45)
at org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService.loadUserByUsername(ClientDetailsUserDetailsService.java:47)
at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:108)
at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:144)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:175)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:169)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:109)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68)
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:111)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:269)
at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:78)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:133)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:130)
at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:249)
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:78)
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:99)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:376)
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.sql.SQLSyntaxErrorException: Table 'bladex.oauth_client_details' doesn't exist
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeQuery(ClientPreparedStatement.java:1003)
at com.alibaba.druid.pool.DruidPooledPreparedStatement.executeQuery(DruidPooledPreparedStatement.java:227)
at org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:678)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:617)
... 77 more
五、若有更多详细信息,请在下面提供。
尝试将blade-core-secure包排除之后,auth工程启动会报错
java.lang.IllegalArgumentException: Could not find class [org.springblade.core.secure.config.RegistryConfiguration]
at org.springframework.util.ClassUtils.resolveClassName(ClassUtils.java:334) ~[spring-core-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.core.annotation.TypeMappedAnnotation.adapt(TypeMappedAnnotation.java:446) ~[spring-core-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.core.annotation.TypeMappedAnnotation.getValue(TypeMappedAnnotation.java:369) ~[spring-core-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.core.annotation.TypeMappedAnnotation.asMap(TypeMappedAnnotation.java:284) ~[spring-core-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.core.annotation.AbstractMergedAnnotation.asAnnotationAttributes(AbstractMergedAnnotation.java:193) ~[spring-core-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.core.type.AnnotatedTypeMetadata.getAnnotationAttributes(AnnotatedTypeMetadata.java:106) ~[spring-core-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.context.annotation.AnnotationConfigUtils.attributesFor(AnnotationConfigUtils.java:285) ~[spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.context.annotation.AnnotationBeanNameGenerator.determineBeanNameFromAnnotation(AnnotationBeanNameGenerator.java:102) ~[spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.context.annotation.AnnotationBeanNameGenerator.generateBeanName(AnnotationBeanNameGenerator.java:81) ~[spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.registerBeanDefinitionForImportedConfigurationClass(ConfigurationClassBeanDefinitionReader.java:160) ~[spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:141) ~[spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:120) ~[spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:331) ~[spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:236) ~[spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:280) ~[spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:96) ~[spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:707) ~[spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:533) ~[spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) ~[spring-boot-2.2.12.RELEASE.jar:2.2.12.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) ~[spring-boot-2.2.12.RELEASE.jar:2.2.12.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:405) ~[spring-boot-2.2.12.RELEASE.jar:2.2.12.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.2.12.RELEASE.jar:2.2.12.RELEASE]
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:140) [spring-boot-2.2.12.RELEASE.jar:2.2.12.RELEASE]
at org.springblade.core.launch.BladeApplication.run(BladeApplication.java:50) [blade-core-launch-2.7.1.RELEASE.jar:na]
at org.springblade.auth.AuthApplication.main(AuthApplication.java:34) [classes/:na]
Caused by: java.lang.ClassNotFoundException: org.springblade.core.secure.config.RegistryConfiguration
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_101]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_101]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[na:1.8.0_101]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_101]
at java.lang.Class.forName0(Native Method) ~[na:1.8.0_101]
at java.lang.Class.forName(Class.java:348) ~[na:1.8.0_101]
at org.springframework.util.ClassUtils.forName(ClassUtils.java:284) ~[spring-core-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.util.ClassUtils.resolveClassName(ClassUtils.java:324) ~[spring-core-5.2.12.RELEASE.jar:5.2.12.RELEASE]
... 24 common frames omitted
主要问题在于blade-scope-api需要依赖blade-core-secure,而blade-core-secure又与blade-auth冲突,因为blade-auth依赖了security。但删除blade-core-secure依赖后,blade-scope-api本身又会报错。
所以正确的做法应该是这样:
1. blade-auth只用于外部业务模块的feign引入调用
2. 不引入blade-scope-api来做业务数据过滤
3. 应该是把blade-scope-api给其他业务工程依赖,然后业务工程对应的api工程参考blade-user-api对外开放feign接口
4. blade-auth引入业务feign,进行调用
5. 业务feign调用后会转到业务工程的controller实现,而业务工程引入了blade-scope-api,会自动进行数据权限的加载
6. 而对于一些需要独立数据库的服务,也可以引入blade-scope-api,因为blade-scope-api底层也是feign的形式前往blade-system获取数据并返回配置
7. 这样的话你的问题就可以解决了
目的主要是想直接用项目中的@PreAuth("hasPermission('xxx:xxx:xxx')")这个注解对子系统进行接口权限校验,按照解决方案进行修改的话,子工程的接口鉴权拦截也会调用自定义的hasPermission方法么?
子工程会调用的,只要不把这个注解写在blade-auth就行。具体实现方式可以看blade-core-secure的相关源码
扫一扫访问 Blade技术社区 移动端