Spring 使用资源服务器启动 2.0 OAuth2 授权服务器
Spring Boot 2.0 OAuth2 Authorization Server with Ressource Server
我试图创建一个授权服务器,它有自己的登录页面和一个资源 Spring Boot 2.0.0 和 spring-security-oauth2 2.3.0。不幸的是,资源服务器的配置似乎不起作用。随着
curl -v localhost:8080/sample
总是重定向 302 到 localhost:8080/login 有或没有令牌。
我的安全配置是
@Configuration
public class SecurityConfiguration {
@Configuration
@Order(1)
@EnableWebSecurity(debug = true)
protected static class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("john").password("{noop}123").roles("User");
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/ping").permitAll()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.csrf()
.and()
.formLogin()
.usernameParameter("username")
.passwordParameter("password")
.loginPage("/login")
.permitAll()
.and()
.rememberMe()
.rememberMeParameter("remember")
.and()
.httpBasic().disable()
.logout().permitAll();
}
}
@Configuration
@EnableResourceServer
@Order(10)
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "Sample";
@Override
public void configure(final ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(RESOURCE_ID);
}
@Override
public void configure(final HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/sample**").authenticated();
}
}
@Configuration
@EnableAuthorizationServer
@Order(Ordered.HIGHEST_PRECEDENCE)
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(final AuthorizationServerSecurityConfigurer security) throws Exception {
security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("ABC").secret("{noop}sec1").autoApprove(true)
.authorizedGrantTypes("authorization_code", "client_credentials", "password", "refresh_token")
.scopes("read", "write")
.redirectUris("http://google.com");
}
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.tokenStore(new InMemoryTokenStore())
.authenticationManager(authenticationManager);
}
}
}
如何正确配置资源服务器?
更新:
我使用 Spring Boot 1.5.10、spring-security-oauth2 2.0.14 和 Spring Boot 2.0.0、spring- 测试了以下配置安全-oauth2 2.3.0。
在 1.5.10 中它工作正常,但在 2.0.0 中我在处理登录时得到 "There was an unexpected error (type=Method Not Allowed, status=405)."。我看到安全过滤器链中缺少 UsernamePasswordAuthenticationFilter。
我错过了 Spring Boot 2.0.0 或 Spring Security 5.0.3 中的重大更改吗?
@Configuration
@EnableWebMvc
@EnableAuthorizationServer
@EnableResourceServer
@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class SecurityConfiguration {
@Configuration
protected static class WebMvcConfiguration extends WebMvcConfigurerAdapter implements WebMvcConfigurer {
@Override
public void addViewControllers(final ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
}
@Configuration
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "Sample";
@Override
public void configure(final ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(RESOURCE_ID);
}
@Override
public void configure(final HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/sample**").authenticated()
;
}
}
@Configuration
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(final AuthorizationServerSecurityConfigurer security) throws Exception {
security
.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()")
;
}
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("ABC")
.secret("{noop}sec1")
.autoApprove(true)
.authorizedGrantTypes("authorization_code", "client_credentials", "password", "refresh_token")
.scopes("read", "write")
.redirectUris("http://google.com")
;
}
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.tokenStore(new InMemoryTokenStore())
.authenticationManager(authenticationManager);
}
}
@Configuration
protected static class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("john")
.password("{noop}123")
.roles("User");
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http
.requestMatchers()
.antMatchers("/ping")
.antMatchers("/login")
.antMatchers("/oauth/**")
.and()
.authorizeRequests()
.antMatchers("/ping").permitAll()
.anyRequest().authenticated()
.and()
.csrf()
.and()
.formLogin()
.usernameParameter("username")
.passwordParameter("password")
.loginPage("/login")
.permitAll()
.and()
.rememberMe()
.rememberMeParameter("remember")
.and()
.httpBasic().disable()
.logout().permitAll();
}
}
}
感谢dur的指点,问题已解决。
此配置有效:
@Configuration
@EnableWebMvc
@EnableAuthorizationServer
@EnableResourceServer
@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class SecurityConfiguration {
@Configuration
protected static class WebMvcConfiguration implements WebMvcConfigurer {
@Override
public void addViewControllers(final ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
}
@Configuration
@Order(2)
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "Sample";
@Override
public void configure(final ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(RESOURCE_ID);
}
@Override
public void configure(final HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/sample**").authenticated()
;
}
}
@Configuration
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(final AuthorizationServerSecurityConfigurer security) throws Exception {
security
.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()")
;
}
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("ABC")
.secret("{noop}sec1")
.autoApprove(true)
.authorizedGrantTypes("authorization_code", "client_credentials", "password", "refresh_token")
.scopes("read", "write")
.redirectUris("http://google.com")
;
}
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.tokenStore(new InMemoryTokenStore())
.authenticationManager(authenticationManager);
}
}
@Configuration
@Order(1)
protected static class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("john")
.password("{noop}123")
.roles("User");
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http
.requestMatchers()
.antMatchers("/ping")
.antMatchers("/login")
.antMatchers("/oauth/**")
.and()
.authorizeRequests()
.antMatchers("/ping").permitAll()
.anyRequest().authenticated()
.and()
.csrf()
.and()
.formLogin()
.usernameParameter("username")
.passwordParameter("password")
.loginPage("/login")
.permitAll()
.and()
.rememberMe()
.rememberMeParameter("remember")
.and()
.httpBasic().disable()
.logout().permitAll();
}
}
}
写了一个基本的 spring boot 2 oauth2 资源服务器和授权服务器,把它放在这里以防有人正在寻找 bootstrap 项目:
https://github.com/indrekru/spring-boot-2-oauth2-resource-server
我试图创建一个授权服务器,它有自己的登录页面和一个资源 Spring Boot 2.0.0 和 spring-security-oauth2 2.3.0。不幸的是,资源服务器的配置似乎不起作用。随着
curl -v localhost:8080/sample
总是重定向 302 到 localhost:8080/login 有或没有令牌。
我的安全配置是
@Configuration
public class SecurityConfiguration {
@Configuration
@Order(1)
@EnableWebSecurity(debug = true)
protected static class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("john").password("{noop}123").roles("User");
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/ping").permitAll()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.csrf()
.and()
.formLogin()
.usernameParameter("username")
.passwordParameter("password")
.loginPage("/login")
.permitAll()
.and()
.rememberMe()
.rememberMeParameter("remember")
.and()
.httpBasic().disable()
.logout().permitAll();
}
}
@Configuration
@EnableResourceServer
@Order(10)
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "Sample";
@Override
public void configure(final ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(RESOURCE_ID);
}
@Override
public void configure(final HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/sample**").authenticated();
}
}
@Configuration
@EnableAuthorizationServer
@Order(Ordered.HIGHEST_PRECEDENCE)
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(final AuthorizationServerSecurityConfigurer security) throws Exception {
security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("ABC").secret("{noop}sec1").autoApprove(true)
.authorizedGrantTypes("authorization_code", "client_credentials", "password", "refresh_token")
.scopes("read", "write")
.redirectUris("http://google.com");
}
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.tokenStore(new InMemoryTokenStore())
.authenticationManager(authenticationManager);
}
}
}
如何正确配置资源服务器?
更新:
我使用 Spring Boot 1.5.10、spring-security-oauth2 2.0.14 和 Spring Boot 2.0.0、spring- 测试了以下配置安全-oauth2 2.3.0。
在 1.5.10 中它工作正常,但在 2.0.0 中我在处理登录时得到 "There was an unexpected error (type=Method Not Allowed, status=405)."。我看到安全过滤器链中缺少 UsernamePasswordAuthenticationFilter。
我错过了 Spring Boot 2.0.0 或 Spring Security 5.0.3 中的重大更改吗?
@Configuration
@EnableWebMvc
@EnableAuthorizationServer
@EnableResourceServer
@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class SecurityConfiguration {
@Configuration
protected static class WebMvcConfiguration extends WebMvcConfigurerAdapter implements WebMvcConfigurer {
@Override
public void addViewControllers(final ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
}
@Configuration
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "Sample";
@Override
public void configure(final ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(RESOURCE_ID);
}
@Override
public void configure(final HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/sample**").authenticated()
;
}
}
@Configuration
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(final AuthorizationServerSecurityConfigurer security) throws Exception {
security
.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()")
;
}
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("ABC")
.secret("{noop}sec1")
.autoApprove(true)
.authorizedGrantTypes("authorization_code", "client_credentials", "password", "refresh_token")
.scopes("read", "write")
.redirectUris("http://google.com")
;
}
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.tokenStore(new InMemoryTokenStore())
.authenticationManager(authenticationManager);
}
}
@Configuration
protected static class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("john")
.password("{noop}123")
.roles("User");
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http
.requestMatchers()
.antMatchers("/ping")
.antMatchers("/login")
.antMatchers("/oauth/**")
.and()
.authorizeRequests()
.antMatchers("/ping").permitAll()
.anyRequest().authenticated()
.and()
.csrf()
.and()
.formLogin()
.usernameParameter("username")
.passwordParameter("password")
.loginPage("/login")
.permitAll()
.and()
.rememberMe()
.rememberMeParameter("remember")
.and()
.httpBasic().disable()
.logout().permitAll();
}
}
}
感谢dur的指点,问题已解决。
此配置有效:
@Configuration
@EnableWebMvc
@EnableAuthorizationServer
@EnableResourceServer
@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class SecurityConfiguration {
@Configuration
protected static class WebMvcConfiguration implements WebMvcConfigurer {
@Override
public void addViewControllers(final ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
}
@Configuration
@Order(2)
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "Sample";
@Override
public void configure(final ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(RESOURCE_ID);
}
@Override
public void configure(final HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/sample**").authenticated()
;
}
}
@Configuration
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(final AuthorizationServerSecurityConfigurer security) throws Exception {
security
.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()")
;
}
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("ABC")
.secret("{noop}sec1")
.autoApprove(true)
.authorizedGrantTypes("authorization_code", "client_credentials", "password", "refresh_token")
.scopes("read", "write")
.redirectUris("http://google.com")
;
}
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.tokenStore(new InMemoryTokenStore())
.authenticationManager(authenticationManager);
}
}
@Configuration
@Order(1)
protected static class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("john")
.password("{noop}123")
.roles("User");
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http
.requestMatchers()
.antMatchers("/ping")
.antMatchers("/login")
.antMatchers("/oauth/**")
.and()
.authorizeRequests()
.antMatchers("/ping").permitAll()
.anyRequest().authenticated()
.and()
.csrf()
.and()
.formLogin()
.usernameParameter("username")
.passwordParameter("password")
.loginPage("/login")
.permitAll()
.and()
.rememberMe()
.rememberMeParameter("remember")
.and()
.httpBasic().disable()
.logout().permitAll();
}
}
}
写了一个基本的 spring boot 2 oauth2 资源服务器和授权服务器,把它放在这里以防有人正在寻找 bootstrap 项目:
https://github.com/indrekru/spring-boot-2-oauth2-resource-server