Spring Boot OAuth2隐式流+;表单登录和请求方法';邮政';不支持的错误
在我的Spring Boot应用程序中,我试图配置OAuth2隐式流。为此,我正在尝试配置自定义登录表单 这是我的配置:Spring Boot OAuth2隐式流+;表单登录和请求方法';邮政';不支持的错误,spring,spring-security,spring-boot,spring-security-oauth2,spring-oauth2,Spring,Spring Security,Spring Boot,Spring Security Oauth2,Spring Oauth2,在我的Spring Boot应用程序中,我试图配置OAuth2隐式流。为此,我正在尝试配置自定义登录表单 这是我的配置: @Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/login").setViewName("login");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private SocialAuthenticationSuccessHandler socialAuthenticationSuccessHandler;
@Autowired
private DBUserDetailsService userDetailsService;
@Value("${social.postLogin.url}")
private String postLoginUrl;
@Override
public void configure(WebSecurity web) throws Exception {
// Spring Security ignores request to static resources such as CSS or JS
// files.
web.ignoring().antMatchers("/static/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http.addFilterBefore(new CorsFilter(), ChannelProcessingFilter.class);
// Set a custom successHandler on the SocialAuthenticationFilter
final SpringSocialConfigurer socialConfigurer = new SpringSocialConfigurer();
socialConfigurer.addObjectPostProcessor(new ObjectPostProcessor<SocialAuthenticationFilter>() {
@Override
public <O extends SocialAuthenticationFilter> O postProcess(O socialAuthenticationFilter) {
socialAuthenticationFilter.setAuthenticationSuccessHandler(socialAuthenticationSuccessHandler);
socialAuthenticationFilter.setPostLoginUrl(postLoginUrl);
return socialAuthenticationFilter;
}
});
http
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/oauth/authorize").authenticated()
//Anyone can access the urls
.antMatchers("/auth/**").permitAll()
.antMatchers("/actuator/health").permitAll()
.antMatchers("/actuator/**").hasAuthority("PERMISSION_READ_ACTUATOR_DATA")
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login")
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
//Adds the SocialAuthenticationFilter to Spring Security's filter chain.
.and()
// apply the configuration from the socialConfigurer (adds the SocialAuthenticationFilter)
.apply(socialConfigurer);
// @formatter:on
}
/**
* Configures the authentication manager bean which processes authentication
* requests.
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
@Configuration
public class OAuth2ServerConfig {
private static final String RESOURCE_ID = "restservice";
@Autowired
private DBUserDetailsService userDetailsService;
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter() {
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
DBUserDetails user = (DBUserDetails) authentication.getUserAuthentication().getPrincipal();
final Map<String, Object> additionalInfo = new HashMap<>();
additionalInfo.put("user_id", user.getUser().getId());
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
OAuth2AccessToken enhancedToken = super.enhance(accessToken, authentication);
return enhancedToken;
}
};
converter.setSigningKey("123");
DefaultAccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter();
DefaultUserAuthenticationConverter userTokenConverter = new DefaultUserAuthenticationConverter();
userTokenConverter.setUserDetailsService(userDetailsService);
accessTokenConverter.setUserTokenConverter(userTokenConverter);
converter.setAccessTokenConverter(accessTokenConverter);
return converter;
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Autowired
private TokenStore tokenStore;
@Autowired
private TokenEnhancer tokenEnhancer;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// @formatter:off
endpoints
.tokenStore(tokenStore)
.tokenEnhancer(tokenEnhancer)
.authenticationManager(this.authenticationManager);
// @formatter:on
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// @formatter:off
clients
.inMemory()
.withClient("clientapp")
.authorizedGrantTypes("password","refresh_token")
//.authorizedGrantTypes("implicit")
.authorities("ROLE_CLIENT")
.scopes("read", "write")
.resourceIds(RESOURCE_ID)
.secret("123456")
.and()
.withClient("clientapp1")
.authorizedGrantTypes("implicit")
.scopes("read", "write")
.autoApprove(true);
// @formatter:on
}
}
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Autowired
private ResourceServerTokenServices tokenService;
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
// @formatter:off
resources
.resourceId(RESOURCE_ID)
.tokenServices(tokenService);
// @formatter:on
}
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.antMatchers("/profile/*").authenticated()
.and().csrf()
.disable().sessionManagement().sessionCreationPolicy(STATELESS);
// @formatter:on
}
}
}
我已成功重定向到位于http://localhost:8080/login
但当我输入用户名/密码并按下“登录”按钮时,我发现以下错误:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sat Sep 24 21:19:44 EEST 2016
There was an unexpected error (type=Method Not Allowed, status=405).
Request method 'POST' not supported
我做错了什么,如何解决这个问题
已更新
在调试中,我可以看到以下输出:
DispatcherServlet with name 'dispatcherServlet' processing POST request for [/login]
2016-09-25 10:04:43 [http-nio-8080-exec-2] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping -
Looking up handler method for path /login
2016-09-25 10:04:43 [http-nio-8080-exec-2] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping -
Did not find handler method for [/login]
2016-09-25 10:04:43 [http-nio-8080-exec-2] DEBUG o.s.w.s.h.SimpleUrlHandlerMapping -
Mapping [/login] to HandlerExecutionChain with handler [org.springframework.web.servlet.mvc.ParameterizableViewController@c85e70] and 1 interceptor
2016-09-25 10:04:43 [http-nio-8080-exec-2] DEBUG o.s.w.s.m.a.ResponseStatusExceptionResolver -
Resolving exception from handler [org.springframework.web.servlet.mvc.ParameterizableViewController@c85e70]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported
2016-09-25 10:04:43 [http-nio-8080-exec-2] DEBUG o.s.w.s.m.s.DefaultHandlerExceptionResolver -
Resolving exception from handler [org.springframework.web.servlet.mvc.ParameterizableViewController@c85e70]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported
2016-09-25 10:04:43 [http-nio-8080-exec-2] WARN o.s.web.servlet.PageNotFound -
Request method 'POST' not supported
2016-09-25 10:04:43 [http-nio-8080-exec-2] DEBUG o.s.s.w.h.writers.HstsHeaderWriter -
Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@16580a4
2016-09-25 10:04:43 [http-nio-8080-exec-2] DEBUG o.s.web.servlet.DispatcherServlet -
Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2016-09-25 10:04:43 [http-nio-8080-exec-2] DEBUG o.s.web.servlet.DispatcherServlet -
Successfully completed request
另外,还有一个关于此问题的问题没有提供答案这是我的ResourceServer配置错误的问题 通过以下配置,一切正常:
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Autowired
private ResourceServerTokenServices tokenService;
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
// @formatter:off
resources
.resourceId(RESOURCE_ID)
.tokenServices(tokenService);
// @formatter:on
}
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.antMatcher("/api/**" )
.authorizeRequests().anyRequest().authenticated()
.and()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(STATELESS);
// @formatter:on
}
}
我今天也遇到了同样的问题,你的回答对我没有帮助,但我找到了解决问题的办法 希望这能帮助其他处于同样位置的人 我的应用程序的问题是,我使用Basic Auth来覆盖我的web应用程序的大部分受保护资源,但我使用OAuth2来保护我允许人们连接的公共API 因此,这导致我的应用程序在两个单独的配置文件中有两个单独的
public void configure(HttpSecurity http)
方法
解决方案是向配置类添加Order
注释
因此,我使用Basic Auth的主配置类为其分配了Order(1)
,而ResourceServerConfigurerAdapter
为其分配了Order(2)
注释
例如:
@EnableWebSecurity
@Order(1)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
/// ... my normal configuration information
protected void configure(HttpSecurity http) {
// my basic auth config
}
}
@Configuration
@Order(2)
public class OAuth2ServerConfig
{
@Configuration
@EnableResourceServer
@Order(3)
protected static class Oauth2ServerConfig extends ResourceServerConfigurerAdapter
{
@Override
public void configure(HttpSecurity http) throws Exception
{
http.authorizeRequests()
.antMatchers("/oauth/**").permitAll()
.antMatchers("/api/v1/**").access("#oauth2.hasScope('read')");
}
}
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServer extends AuthorizationServerConfigurerAdapter
{
// authorization server settings
}
}
从jsp中删除
method=“post”
。此外,您还必须为/error
请求添加请求处理程序。非常爱您@Trevor xD
DispatcherServlet with name 'dispatcherServlet' processing POST request for [/login]
2016-09-25 10:04:43 [http-nio-8080-exec-2] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping -
Looking up handler method for path /login
2016-09-25 10:04:43 [http-nio-8080-exec-2] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping -
Did not find handler method for [/login]
2016-09-25 10:04:43 [http-nio-8080-exec-2] DEBUG o.s.w.s.h.SimpleUrlHandlerMapping -
Mapping [/login] to HandlerExecutionChain with handler [org.springframework.web.servlet.mvc.ParameterizableViewController@c85e70] and 1 interceptor
2016-09-25 10:04:43 [http-nio-8080-exec-2] DEBUG o.s.w.s.m.a.ResponseStatusExceptionResolver -
Resolving exception from handler [org.springframework.web.servlet.mvc.ParameterizableViewController@c85e70]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported
2016-09-25 10:04:43 [http-nio-8080-exec-2] DEBUG o.s.w.s.m.s.DefaultHandlerExceptionResolver -
Resolving exception from handler [org.springframework.web.servlet.mvc.ParameterizableViewController@c85e70]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported
2016-09-25 10:04:43 [http-nio-8080-exec-2] WARN o.s.web.servlet.PageNotFound -
Request method 'POST' not supported
2016-09-25 10:04:43 [http-nio-8080-exec-2] DEBUG o.s.s.w.h.writers.HstsHeaderWriter -
Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@16580a4
2016-09-25 10:04:43 [http-nio-8080-exec-2] DEBUG o.s.web.servlet.DispatcherServlet -
Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2016-09-25 10:04:43 [http-nio-8080-exec-2] DEBUG o.s.web.servlet.DispatcherServlet -
Successfully completed request
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Autowired
private ResourceServerTokenServices tokenService;
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
// @formatter:off
resources
.resourceId(RESOURCE_ID)
.tokenServices(tokenService);
// @formatter:on
}
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.antMatcher("/api/**" )
.authorizeRequests().anyRequest().authenticated()
.and()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(STATELESS);
// @formatter:on
}
}
@EnableWebSecurity
@Order(1)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
/// ... my normal configuration information
protected void configure(HttpSecurity http) {
// my basic auth config
}
}
@Configuration
@Order(2)
public class OAuth2ServerConfig
{
@Configuration
@EnableResourceServer
@Order(3)
protected static class Oauth2ServerConfig extends ResourceServerConfigurerAdapter
{
@Override
public void configure(HttpSecurity http) throws Exception
{
http.authorizeRequests()
.antMatchers("/oauth/**").permitAll()
.antMatchers("/api/v1/**").access("#oauth2.hasScope('read')");
}
}
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServer extends AuthorizationServerConfigurerAdapter
{
// authorization server settings
}
}