Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/415.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring security 使用过期的承载令牌访问资源失败,http代码为500_Spring Security_Spring Security Oauth2_Spring Cloud - Fatal编程技术网

Spring security 使用过期的承载令牌访问资源失败,http代码为500

Spring security 使用过期的承载令牌访问资源失败,http代码为500,spring-security,spring-security-oauth2,spring-cloud,Spring Security,Spring Security Oauth2,Spring Cloud,这是我在SpringBoot 1.2.3.0版本中的应用程序设置 认证应用程序 @SpringBootApplication @RestController @SessionAttributes("authorizationRequest") @EnableResourceServer public class AuthserverApplication extends WebMvcConfigurerAdapter { public static void main(String[]

这是我在SpringBoot 1.2.3.0版本中的应用程序设置

认证应用程序

@SpringBootApplication
@RestController
@SessionAttributes("authorizationRequest")
@EnableResourceServer
public class AuthserverApplication extends WebMvcConfigurerAdapter {

    public static void main(String[] args) {
        SpringApplication.run(AuthserverApplication.class, args);
    }

    @RequestMapping("/user")
    public Principal user(Principal user) {
        return user;
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("login");
        registry.addViewController("/oauth/confirm_access").setViewName("authorize");
    }

    @Configuration
    @Order(-10)
    protected static class LoginConfig extends WebSecurityConfigurerAdapter {

        @Autowired
        private AuthenticationManager authenticationManager;

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // @formatter:off
            http.formLogin().loginPage("/login").permitAll()
                .and().requestMatchers()
                    .antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access")
                .and().authorizeRequests()
                    .anyRequest().authenticated();
            // @formatter:on
        }

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.parentAuthenticationManager(authenticationManager);
        }
    }

    @Configuration
    @EnableAuthorizationServer
    protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {

        @Autowired
        private AuthenticationManager authenticationManager;

        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            endpoints.authenticationManager(authenticationManager);
        }

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients.inMemory().withClient("acme").secret("acmesecret")
                    .authorizedGrantTypes("authorization_code", "refresh_token", "password").scopes("openid")
                    .and().withClient("trusted").secret("shuush").authorizedGrantTypes("client_credentials").scopes("openid");
        }

    }
}
使用application.properties

server.port=9999
security.user.password=password
server.contextPath=/uaa
server.port: 8801
spring.oauth2.resource.userInfoUri: http://localhost:9999/uaa/user
资源应用程序

@SpringBootApplication
@EnableOAuth2Resource
@RestController
public class ResourceApplication {

    @RequestMapping("/resource")
    public Map<String, String> resource() {
        Map<String, String> t = new HashMap<String, String>();
        t.put("Hello", "World!");
        return t;
    }

    public static void main(String[] args) {
        SpringApplication.run(ResourceApplication.class, args);
    }

}
客户端:

步骤1:我使用curl获取承载令牌

curl -v -u trusted:shuush -d "grant_type=client_credentials" http://localhost:9999/uaa/oauth/token
得到答复

{"access_token":"a9983ae3-e4db-4702-8039-7ecfd7472594","token_type":"bearer","expires_in":43095,"scope":"openid"}
步骤2:我访问资源

curl -v -H "Authorization: Bearer a9983ae3-e4db-4702-8039-7ecfd7472594" http://localhost:8801/resource
这给了我一个漂亮的回答

{"Hello":"World!"}
步骤3:在我的令牌过期很久之后,我再次尝试访问资源(与步骤2相同),我希望收到401 http代码,其响应类似 {“error”:“unauthorized”,“error_description”:“token expired…” 然而,我得到了500个代码和响应

{
    "timestamp": 1433861559805,
    "status": 500,
    "error": "Internal Server Error",
    "exception": "org.springframework.security.oauth2.client.resource.UserRedirectRequiredException",
    "message": "A redirect is required to get the users approval",
    "path": "/resource"
}
堆栈跟踪:

org.springframework.security.oauth2.client.resource.UserRedirectRequiredException: A redirect is required to get the users approval
    at org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.getRedirectForAuthorization(AuthorizationCodeAccessTokenProvider.java:347)
    at org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.obtainAccessToken(AuthorizationCodeAccessTokenProvider.java:194)
    at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:221)
    at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:173)
    at org.springframework.security.oauth2.client.OAuth2RestTemplate.createRequest(OAuth2RestTemplate.java:105)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:565)
    at org.springframework.security.oauth2.client.OAuth2RestTemplate.doExecute(OAuth2RestTemplate.java:143)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:530)
    at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:262)
    at org.springframework.cloud.security.oauth2.resource.UserInfoTokenServices.getMap(UserInfoTokenServices.java:105)
    at org.springframework.cloud.security.oauth2.resource.UserInfoTokenServices.loadAuthentication(UserInfoTokenServices.java:58)
    at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager.authenticate(OAuth2AuthenticationManager.java:83)
    at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter.doFilter(OAuth2AuthenticationProcessingFilter.java:150)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.boot.actuate.autoconfigure.MetricFilterAutoConfiguration$MetricsFilter.doFilterInternal(MetricFilterAutoConfiguration.java:90)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1086)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:659)
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1558)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1515)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
不知道我是否缺少一些配置。有什么建议吗

更新1: 奇怪的是,有时我会得到不同的反应

{"error":"invalid_request","error_description":"Possible CSRF detected - state parameter was present but no state could be found"}
少量调试显示端点
http://localhost:9999/uaa/user
确实会抛出类似于
{error=“invalid_token”,error\u description=“invalid access token…”的错误
,但会被吞没为抛出org.springframework.security.oauth2.client.http.AccessTokenRequiredException

进一步的
org.springframework.security.oauth2.client.OAuth2RestTemplate
吞咽
org.springframework.security.oauth2.client.http.AccessTokenRequiredException
并通过在抛出完全不同的错误时删除令牌来重试坏令牌


我相信这是一个bug,除非我的配置有问题

错误来自SpringCloud中的
UserInfoTokenServices
。我建议你在那里提出一个问题。如果你想预测一下未来,Spring Boot 1.3也有这些功能(即Spring Cloud将在某个时候删除它)。谢谢@DaveSyer。我希望修复程序和Spring Boot 1.3也能解决不一致的错误消息