我正在使用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;
}
}
请帮帮我..
答案 0 :(得分:3)
MarshallingHttpMessageConverter
不够智能,无法转换访问令牌。这就是为什么Spring OAuth有JaxbOAuth2AccessTokenMessageConverter
(以及JaxbOAuth2ExceptionMessageConverter
)的原因。您需要这些,并且在OAuth2AuthenticationEntryPoint
和OAuth2AccessDeniedHandler
中也需要它们在/token
端点安全性中使用(假设您的客户端希望安全性错误也以XML格式呈现)。目前的@EnableAuthorizationServer
支持允许您注入自己的AuthenticationEntryPoint
,但您需要自己延长AuthorizationServerSecurityConfiguration
来覆盖AccessDeniedHandler
。