带有弹簧会话和安全性的春季启动.RMI 失败并显示 401



我正在使用带有 spring 安全性的 Spring boot 和带有 redis 的 Spring Session 进行身份验证和授权。有两个单独的项目正在运行,我想将它们与RMI tunneled over HTTP连接起来。即使我在HttpInvokerProxyFactoryBean中使用了setRemoteInvocationFactory 因为第二个服务抛出了 401。我收到内部服务器错误。解决方法是什么?

我正在标头中传递会话 ID 作为x-auth-token.我应该通过服务调用程序传递相同的内容吗?

这是代码

出口商:

@Configuration
@EnableAutoConfiguration
public class ServiceExporter {
    @Bean(name = "/rmi")
    HttpInvokerServiceExporter accountService(@Autowired rmiimpl rmi) {
        HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter();
        exporter.setServiceInterface(rmiinterface.class);
        exporter.setService(rmi);
        return exporter;
    }
}

调用程序:

@Configuration
@EnableAutoConfiguration
public class test {
    @Bean
    public HttpInvokerProxyFactoryBean invoker() {
        HttpInvokerProxyFactoryBean invoker = new HttpInvokerProxyFactoryBean();
        String serviceURL = "http://localhost:8081/rmi";
        invoker.setServiceUrl(serviceURL);
        invoker.setServiceInterface(rmiinterface.class);
        invoker.setRemoteInvocationFactory(remoteinvocation());
        return invoker;
    }
    @Bean
    RemoteInvocationFactory remoteinvocation() {
        return new ContextPropagatingRemoteInvocationFactory();
    }
}

安全配置:

@Configuration
@EnableWebSecurity
public class SessionSecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    public HttpSessionStrategy httpSessionStrategy() {
        return new HeaderHttpSessionStrategy();
    }
    @Override
    protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("admin").password("adminPass").roles("ADMIN");
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // https://www.baeldung.com/spring-security-session
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
        http.csrf().disable().authorizeRequests() //
                .antMatchers("/auth/*").fullyAuthenticated() //
                .and().requestCache() //
                .requestCache(new NullRequestCache()) //
                .and().httpBasic();
    }
}

例外:

java.io.IOException: Did not receive successful HTTP response: status code = 401, status message = [null]
    at org.springframework.remoting.httpinvoker.SimpleHttpInvokerRequestExecutor.validateResponse(SimpleHttpInvokerRequestExecutor.java:188) ~[spring-web-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.remoting.httpinvoker.SimpleHttpInvokerRequestExecutor.doExecuteRequest(SimpleHttpInvokerRequestExecutor.java:92) ~[spring-web-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.remoting.httpinvoker.AbstractHttpInvokerRequestExecutor.executeRequest(AbstractHttpInvokerRequestExecutor.java:137) ~[spring-web-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.executeRequest(HttpInvokerClientInterceptor.java:202) ~[spring-web-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.executeRequest(HttpInvokerClientInterceptor.java:184) ~[spring-web-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.invoke(HttpInvokerClientInterceptor.java:150) ~[spring-web-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) ~[spring-aop-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at com.sun.proxy.$Proxy66.rmitext(Unknown Source) ~[na:na]
    at com.example.controller.AuthController.test(AuthController.java:27) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_191]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_191]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_191]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_191]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) ~[spring-web-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) ~[spring-webmvc-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:854) ~[spring-webmvc-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:765) ~[spring-webmvc-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) ~[spring-webmvc-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) ~[spring-webmvc-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) ~[spring-webmvc-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) ~[tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.39.jar:8.5.39]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:158) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177) ~[spring-security-web-4.2.12.RELEASE.jar:4.2.12.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:347) ~[spring-web-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:263) ~[spring-web-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) ~[spring-web-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:171) ~[spring-session-1.3.5.RELEASE.jar:na]
    at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:80) ~[spring-session-1.3.5.RELEASE.jar:na]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.23.RELEASE.jar:4.3.23.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) ~[tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) [tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137) [tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:798) [tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806) [tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498) [tomcat-embed-core-8.5.39.jar:8.5.39]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.39.jar:8.5.39]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_191]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_191]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.39.jar:8.5.39]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_191]

不知道缺少什么。

终于想通了。

众所周知,Spring Security默认从cookie读取会话ID。在这种情况下,由于我使用了@Bean public HttpSessionStrategy因此它从标头x-auth-token读取。

每当HttpInvokerProxyFactoryBean尝试连接时,都会传播身份验证上下文,但由于它是 HTTP 调用,默认的 spring 会话过滤器会尝试读取会话 ID 并验证相同的内容。由于此处会话 ID 未传输,因此它会抛出 401。

为了修复它。我需要在 HTTP 调用程序中设置header。如果使用cookie,则同样适用。由于HttpInvokerProxyFactoryBean使用SimpleHttpInvokerRequestExecutor.我通过扩展它创建了一个新类,并通过覆盖 prepareConnection 添加了标头。我在调用程序中使用setHttpInvokerRequestExecutor来设置执行器以调用新类。

这是代码。

调用程序:

@Configuration
@EnableAutoConfiguration
public class test {
    @Bean
    public HttpInvokerProxyFactoryBean invoker() {
        HttpInvokerProxyFactoryBean invoker = new HttpInvokerProxyFactoryBean();
        String serviceURL = "http://localhost:8081/rmi";
        invoker.setServiceUrl(serviceURL);
        invoker.setServiceInterface(rmiinterface.class);
        invoker.setHttpInvokerRequestExecutor(httpInvokerRequestExecutor()); //call to the bean
        return invoker;
    }
    @Bean
    public SimpleHttpInvokerRequestExecutor httpInvokerRequestExecutor() {
        return new CustomHttpInvokerRequestExecutor();
    }
}
class CustomHttpInvokerRequestExecutor extends SimpleHttpInvokerRequestExecutor {
    @Autowired
    HttpSession session;
    @Override
    protected void prepareConnection(HttpURLConnection connection, int contentLength) throws IOException {
        // adding header.
        connection.addRequestProperty("x-auth-token", session.getId());
        super.prepareConnection(connection, contentLength);
    }
}

现在它开始工作了。

最新更新