Pranav
Pranav

Reputation: 120

get response from spring oauth2 token request as xml

I am implementing a oauth2 rest server using spring 4 and spring oauth2. Response can be either xml or json as specifeid by the client request header. But am getting issues from oauth2 when ever I try to access the token it supports only JSON (application/json), its not supporting xml(application/xml).

Am getting error as:

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

My security configuration is as follows:

@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(); 
    } 
}

My response as JSON is:

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

I want it as XML

My MVC Configuration is as follows:

@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; 
    } 

} 

please help me..

Upvotes: 1

Views: 2478

Answers (1)

Dave Syer
Dave Syer

Reputation: 58124

MarshallingHttpMessageConverter is not smart enough to convert access tokens. that's why Spring OAuth has a JaxbOAuth2AccessTokenMessageConverter (and also a JaxbOAuth2ExceptionMessageConverter). You need those, and you also need them in the OAuth2AuthenticationEntryPoint and OAuth2AccessDeniedHandler that get used in the /token endpoint security (assuming your client wants Security errors to be rendered in XML as well). The current @EnableAuthorizationServer support lets you inject your own AuthenticationEntryPoint, but you'll need to extend AuthorizationServerSecurityConfiguration yourself to override the AccessDeniedHandler.

Upvotes: 3

Related Questions