从spring oauth2令牌请求获得响应为xml

时间:2014-11-13 06:14:50

标签: spring spring-mvc jackson spring-security-oauth2

我正在使用spring 4和spring oauth2实现oauth2 rest服务器。 客户端请求标头的响应可以是xml或json作为specifeid。 但是当我尝试访问它只支持JSON(application / json)的令牌时,我从oauth2获得问题,它不支持xml(application / xml)。

我收到的错误是:

HTTP Status 406 -
type Status report
message
description The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers.
Apache Tomcat/7.0.54

我的安全配置如下:

@Configuration 
@EnableWebSecurity(debug = true) 
@ComponentScan(basePackages = { "org.bluez.logiczweb.config.security.handler" }) 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 
    private final static String applicationName = "crm"; 

    @Configuration 
    @EnableResourceServer 
    protected static class ResourceServerConfiguration extends 
            ResourceServerConfigurerAdapter { 

        @Autowired 
        private HeaderOnlyOAuth2ExceptionRenderer headerOnlyExceptionRender; 

        @Override 
        public void configure(ResourceServerSecurityConfigurer resources) { 
            resources.resourceId(applicationName); 
        } 

        public void configure(HttpSecurity http) throws Exception { 

            http.csrf().disable(); 
            http.sessionManagement().sessionCreationPolicy( 
                    SessionCreationPolicy.STATELESS); 
            http.requestMatchers().and().authorizeRequests() 
                    .antMatchers("/rest/accounts") 
                    .access("#oauth2.hasScope('read')").and().httpBasic() 
                    .authenticationEntryPoint(clientAuthenticationEntryPoint()); 

            // // .apply(new OAuth2ServerConfigurer()) 
            // .tokenStore(new InMemoryTokenStore()) 
            // .resourceId(applicationName); 

        } 

        @Bean 
        public OAuth2AccessDeniedHandler oauthAccessDeniedHandler() { 
            OAuth2AccessDeniedHandler accessDeniedHandler = new OAuth2AccessDeniedHandler(); 
            accessDeniedHandler.setExceptionRenderer(headerOnlyExceptionRender); 
            return accessDeniedHandler; 
        } 

        @Bean 
        public OAuth2AuthenticationEntryPoint clientAuthenticationEntryPoint() { 
            OAuth2AuthenticationEntryPoint authenticationEntryPoint = new OAuth2AuthenticationEntryPoint(); 

            authenticationEntryPoint.setRealmName("sparklr2/client"); 
            authenticationEntryPoint.setTypeName("Basic"); 
            authenticationEntryPoint 
                    .setExceptionRenderer(headerOnlyExceptionRender); 
            return authenticationEntryPoint; 
        } 
    } 

    @Configuration 
    @EnableAuthorizationServer 
    protected static class AuthorizationServerConfiguration extends 
            AuthorizationServerConfigurerAdapter { 

        @Autowired 
        private TokenStore tokenStore; 

        @Autowired 
        private AuthenticationManager authenticationManager; 

        public void configure(ClientDetailsServiceConfigurer clients) 
                throws Exception { 
            final String scopes[] = "read,write,trust".split(","); 
            final String secret = "123456"; 
            final String[] authorizedGrantTypes = { "password", 
                    "authorization_code", "refresh_token" }; 
            final String authorities = "ROLE_USER"; 
            clients.inMemory().withClient("android-crm") 
                    .resourceIds(applicationName).scopes(scopes) 
                    .authorities(authorities) 
                    .authorizedGrantTypes(authorizedGrantTypes).secret(secret) 
                    .and().withClient("ios-crm").resourceIds(applicationName) 
                    .scopes(scopes).authorities(authorities) 
                    .authorizedGrantTypes(authorizedGrantTypes).secret(secret); 
        } 

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

        @Override 
        public void configure(AuthorizationServerSecurityConfigurer oauthServer) 
                throws Exception { 
            oauthServer.realm("sparklr2/client"); 
        } 

        @Bean 
        public ApprovalStore approvalStore() throws Exception { 
            TokenApprovalStore store = new TokenApprovalStore(); 
            store.setTokenStore(tokenStore); 
            return store; 
        } 

        /* 
         * @Bean public OAuth2AccessDeniedHandler oauthAccessDeniedHandler(){ 
         * OAuth2AccessDeniedHandler accessDeniedHandler=new 
         * OAuth2AccessDeniedHandler(); 
         *  
         * return accessDeniedHandler; } 
         */ 

    } 

    @Bean 
    public AuthenticationManager authenticationManagerBean() throws Exception { 
        return super.authenticationManagerBean(); 
    } 

    @Bean 
    PasswordEncoder passwordEncoder() { 
        return NoOpPasswordEncoder.getInstance(); 
    } 

    @Bean 
    TextEncryptor textEncryptor() { 
        return Encryptors.noOpText(); 
    } 

    @Bean 
    public UserDetailsService userDetailsServiceBean() throws Exception { 
        return super.userDetailsServiceBean(); 
    } 

    protected void configure(AuthenticationManagerBuilder authManagerBuilder) 
            throws Exception { 

        authManagerBuilder.userDetailsService(userDetailsServiceBean()) 
                .passwordEncoder(passwordEncoder()).and() 
                .inMemoryAuthentication().withUser("admin").password("admin") 
                .roles("ADMIN", "USER"); 
    } 

    @Bean 
    public TokenStore tokenStore() { 
        return new InMemoryTokenStore(); 
    } 
}

我对JSON的回答是:

{
"access_token": "27f93b60-a2ab-4ae6-90c9-81124cc7d10b",
"token_type": "bearer",
"refresh_token": "6bb643cf-3eda-402a-bb6d-5f3b05e56bee",
"expires_in": 43199,
"scope": "read"
}

我想要它作为XML

我的MVC配置如下:

@EnableWebMvc 
@Configuration 
public class WebMVCConfiguration extends WebMvcConfigurationSupport { 
    @Bean 
    public ExceptionHandlerExceptionResolver exceptionHandlerExceptionResolver() { 
        ExceptionHandlerExceptionResolver exceptionResolver = new ExceptionHandlerExceptionResolver(); 
        exceptionResolver.setOrder(0); 
        exceptionResolver.setMessageConverters(messageConverters()); 
        return exceptionResolver; 
    } 

    @Bean 
    public List> messageConverters() { 
        List> messageConverters = new ArrayList>(); 
        messageConverters.add(jsonHttpMessageConverter()); 
//        messageConverters.add(stringHttpMessageConverter()); 
        messageConverters.add(xmlConverter()); 
        return messageConverters; 
    } 

    @Bean 
    public StringHttpMessageConverter stringHttpMessageConverter() { 
        return new StringHttpMessageConverter(); 
    } 

    @Bean 
    public MappingJackson2HttpMessageConverter jsonHttpMessageConverter() { 
        return new MappingJackson2HttpMessageConverter(); 
    } 

    @Bean 
    public ByteArrayHttpMessageConverter byteArrayHttpMessageConverter() { 
        return new ByteArrayHttpMessageConverter(); 
    } 

    @Bean 
    public RequestMappingHandlerAdapter requestMappingHandlerAdapter() { 
        RequestMappingHandlerAdapter adapter = super 
                .requestMappingHandlerAdapter(); 
        adapter.setOrder(0); 

        adapter.getMessageConverters().addAll(messageConverters()); 
        adapter.getMessageConverters().add(byteArrayHttpMessageConverter()); 
        return adapter; 

    } 

    @Bean 
    public Jaxb2Marshaller jaxbMarshaller() { 
        Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller(); 
        jaxb2Marshaller 
                .setPackagesToScan("org.bluez.logiczweb.core.models.vo.*"); 
        return jaxb2Marshaller; 
    } 

    @Bean 
    public MarshallingHttpMessageConverter xmlConverter() { 
        MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter( 
                jaxbMarshaller()); 
        converter.setSupportedMediaTypes(Arrays 
                .asList(MediaType.APPLICATION_XML)); 
        return converter; 
    } 

} 

请帮帮我..

1 个答案:

答案 0 :(得分:3)

MarshallingHttpMessageConverter不够智能,无法转换访问令牌。这就是为什么Spring OAuth有JaxbOAuth2AccessTokenMessageConverter(以及JaxbOAuth2ExceptionMessageConverter)的原因。您需要这些,并且在OAuth2AuthenticationEntryPointOAuth2AccessDeniedHandler中也需要它们在/token端点安全性中使用(假设您的客户端希望安全性错误也以XML格式呈现)。目前的@EnableAuthorizationServer支持允许您注入自己的AuthenticationEntryPoint,但您需要自己延长AuthorizationServerSecurityConfiguration来覆盖AccessDeniedHandler