我有一个Spring Boot(1.2.1.release)应用程序,它在一个应用程序实例中为OAuth2(2.0.6.release)授权和资源服务器提供服务。它使用自定义的UserDetailsService
实现,该实现利用MongoTemplate
在MongoDB中搜索用户。在/oauth/token
上使用grant_type=password
进行身份验证,以及在调用特定资源时使用authorization:Bearer{token}
头进行身份验证。
现在我想在服务器上添加简单的OAuth确认对话框,这样我就可以在API文档中对受保护资源进行身份验证和授权,例如Swagger UI调用。以下是我到目前为止所做的:
@Configuration
@SessionAttributes("authorizationRequest")
class OAuth2ServerConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.addViewController("/oauth/confirm_access").setViewName("authorize");
}
@Configuration
@Order(2)
protected static class LoginConfig extends WebSecurityConfigurerAdapter implements ApplicationEventPublisherAware {
@Autowired
UserDetailsService userDetailsService
@Autowired
PasswordEncoder passwordEncoder
ApplicationEventPublisher applicationEventPublisher
@Bean
DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider()
provider.passwordEncoder = passwordEncoder
provider.userDetailsService = userDetailsService
return provider
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.parentAuthenticationManager(authenticationManagerBean())
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder())
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
//return super.authenticationManagerBean()
ProviderManager providerManager = new ProviderManager([daoAuthenticationProvider()], super.authenticationManagerBean())
providerManager.setAuthenticationEventPublisher(new DefaultAuthenticationEventPublisher(applicationEventPublisher))
return providerManager
}
@Bean
public PasswordEncoder passwordEncoder() {
new BCryptPasswordEncoder(5)
}
}
@Configuration
@EnableResourceServer
protected static class ResourceServer extends ResourceServerConfigurerAdapter {
@Value('${oauth.resourceId}')
private String resourceId
@Autowired
@Qualifier('authenticationManagerBean')
private AuthenticationManager authenticationManager
@Override
public void configure(HttpSecurity http) throws Exception {
http.setSharedObject(AuthenticationManager.class, authenticationManager)
http.csrf().disable()
http.httpBasic().disable()
http.formLogin().loginPage("/login").permitAll()
//http.authenticationProvider(daoAuthenticationProvider())
http.anonymous().and()
.authorizeRequests()
.antMatchers('/login/**').permitAll()
.antMatchers('/uaa/register/**').permitAll()
.antMatchers('/uaa/activate/**').permitAll()
.antMatchers('/uaa/password/**').permitAll()
.antMatchers('/uaa/account/**').hasAuthority('ADMIN')
.antMatchers('/api-docs/**').permitAll()
.antMatchers('/admin/**').hasAuthority('SUPERADMIN')
.anyRequest().authenticated()
//http.sessionManagement().sessionCreationPolicy(STATELESS)
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(resourceId)
resources.authenticationManager(authenticationManager)
}
}
@Configuration
@EnableAuthorizationServer
protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {
@Value('${oauth.clientId}')
private String clientId
@Value('${oauth.secret:}')
private String secret
@Value('${oauth.resourceId}')
private String resourceId
@Autowired
@Qualifier('authenticationManagerBean')
private AuthenticationManager authenticationManager
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
return new JwtAccessTokenConverter();
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.checkTokenAccess("permitAll()")
oauthServer.allowFormAuthenticationForClients()
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager)
.accessTokenConverter(accessTokenConverter())
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient(clientId)
.secret(secret)
.authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
.authorities("USER", "ADMIN")
.scopes("read", "write", "trust")
.resourceIds(resourceId)
}
}
}
主要问题是我不能使两者(web登录表单和头部的OAuth2授权令牌)运行。如果ResourceServer
获得更高的优先级,那么OAuth2令牌授权就可以工作,但是我不能使用web表单登录。另一方面,如果我将更高的优先级设置为LoginConfig
类,那么OAuth2令牌授权将停止工作。
我发现,在这种情况下,问题是由未注册的OAuth2AuthenticationProcessingFilter
引起的。我试图在ResourceServer.configure(HttpSecurity http)
方法中手动注册它,但它不起作用--我可以在FilterChain列表中看到过滤器,但它没有被触发。这不是修复它的好方法,因为在ResourceServer初始化期间有很多其他的魔法,所以我转到第二种情况。
在这种情况下,主要问题是默认情况下UsernamePasswordAuthenticationFilter
找不到正确配置的AuthenticationProvider
实例(在ProviderManager
中)。当我尝试通过以下方式手动添加它时:
http.authenticationProvide(daoAuthenticationProvider())
它得到一个,但是在本例中没有定义AuthenticationEventPublisher
,并且成功的身份验证不能发布到其他组件。事实上,在下一次迭代中,它将被AnonymousAuthenticationToken
所取代。这就是为什么我试图手动定义AuthenticationManager
实例,其中包含DAOAuthenticationProvider
:
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
//return super.authenticationManagerBean()
ProviderManager providerManager = new ProviderManager([daoAuthenticationProvider()], super.authenticationManagerBean())
providerManager.setAuthenticationEventPublisher(new DefaultAuthenticationEventPublisher(applicationEventPublisher))
return providerManager
}
我认为它会起作用,但是在向已注册的筛选器提供AuthenticationManager
实例时有一个不同的问题。事实证明,每个筛选器都使用SharedObjects
组件手动注入AuthenticationManager
:
authFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));
这里的问题是,您不能保证有一个正确的实例集,因为有一个简单的HashMap(在GitHub上查看)用于存储特定的共享对象,并且可以随时更改。我试着把它放进去:
http.setSharedObject(AuthenticationManager.class, authenticationManager)
但是在我到达读取它的地方之前,它已经被默认实现替换了。我用调试器检查了它,看起来每个新筛选器都有一个新的authentication Manager实例。
我的问题是:我做得对吗?如何设置授权服务器,将资源服务器集成到一个应用程序中,并使用登录表单(OAuth2对话框)工作?也许可以用一种不同的、容易得多的方式来完成。如果有任何帮助,我将不胜感激。
这是解决问题的办法。看一下这个示例性的Groovy
类:
@Configuration
@EnableResourceServer
class ResourceServer extends ResourceServerConfigurerAdapter {
@Value('${oauth.resourceId}')
private String resourceId
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
http.httpBasic().disable()
http.requestMatchers().antMatchers('/admin/**', '/uaa/**')
.and().authorizeRequests()
.antMatchers('/uaa/authenticated/**').authenticated()
.antMatchers('/uaa/register/**').permitAll()
.antMatchers('/uaa/activate/**').permitAll()
.antMatchers('/uaa/password/**').permitAll()
.antMatchers('/uaa/auth/**').permitAll()
.antMatchers('/uaa/account/**').hasAuthority('ADMIN')
.antMatchers('/admin/**').hasAuthority('ADMIN')
.anyRequest().authenticated()
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(resourceId);
}
}
基本上,要将OAuth2.0身份验证与web表单身份验证并行运行,您必须将
http.requestMatchers().antMatchers('/path/1/**', '/path/2/**')
设置为配置类。我以前的配置忽略了这一重要部分,因此只有OAuth2.0参与了身份验证过程。
我正在使用Spring Boot,我希望我的应用程序托管OAuth2资源服务器,以便在同一服务器上访问我的apiendpoint。我还需要有一个网页界面,通过表格登录的安全页面。 例如,我有apiendpoint/api/v1/**,在这里只能通过从oauth2资源服务器获得令牌来发出请求。 此外,还有像/account/**这样的endpoint,用户需要通过表单登录。 所有这些现在都需要放在一
问题内容: 随着Spring Security 4的发布及其对测试的增强支持,我想更新我当前的Spring Security oauth2资源服务器测试。 目前,我有一个帮助程序类,用于建立与测试连接到实际应用程序的使用,以为我的测试请求有效令牌。然后,此resttemplate用于在s中发出请求。 我想利用Spring Security 4中的新测试支持,放弃对实际AuthorizationSe
在Spring Security 4发布之后,我想更新我当前的Spring Security oauth2资源服务器测试。 目前,我有一个helper类,它使用设置,并使用一个test连接到一个实际的来为我的测试请求一个有效的令牌。然后使用此resttemplate在我的中发出请求。 通过利用Spring Security4中的新测试支持,我希望在测试中放弃对实际AuthorizationServ
我正在学习Spring Boot Security入门第五部分,以保护我的RESTful微服务。 我打算实现的简单流程是:- > 如果未经身份验证,用户将被重定向到一个自定义登录页,地址是'/login'。 用户提供他的凭据。 上面提到的链接中的入门指南使用了在。properties或。yml文件中配置的基本Auth和虚拟用户。 这是我尝试配置的方式:- 单击授权endpoint会将我重定向到“h
我是Spring安全 4 的新手。我已经用支柱 2 和Spring安全性做了一个简单的应用程序。我正在使用自定义登录表单。发生的事情是当我提交登录表单时,我被重定向到 http://localhost:8080/SpringSecurity/admin 但仍然收到以下错误 HTTP状态404- /SpringSecurity/admin 类型状态报告 message/SpringSecurity/
我正在尝试使用Spring构建一个OAuth2授权服务器。问题是我无法让它与登录和授权表单以及资源服务器一起使用oAuth2令牌检索用户数据。 这是我的主要配置,除了用户服务和存储库... 网络安全配置 授权服务器配置 资源服务器配置 用户控制器 正如你所看到的,我给他们下了订单。问题是,如果WebSecurityConfig是第一个,我可以进入/login和/oauth/authorize屏幕,