spring-boot - 如何将 ResourceServer 添加到现有的 spring 安全配置
问题描述
我使用以下安全配置进行授权。我现在想向这个项目添加令牌安全端点。
但是,每当我向安全端点发送请求时,我总是会发现自己被重定向到登录页面(“/oauth_login”),就好像我未经授权一样。我在这里做错了什么?我尝试对此进行调试,当我尝试使用有效令牌访问端点时,似乎从未调用过decode()
my 的覆盖函数。accessTokenConverter
这是我已经拥有的安全配置:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@PropertySource("application.properties")
@Order(1)
class SecurityConfig(
private val userDetailsService: CustomUserDetailsService,
private val inMemoryClientRegistrationRepository: InMemoryClientRegistrationRepository,
private val secretAuthenticationFilter: SecretAuthenticationFilter
) : WebSecurityConfigurerAdapter() {
@Bean
@Throws(Exception::class)
override fun authenticationManager() = super.authenticationManager()
@Throws(Exception::class)
override fun configure(auth: AuthenticationManagerBuilder?) {
auth!!.userDetailsService(userDetailsService)
.passwordEncoder(BCryptPasswordEncoder(10))
}
@Throws(Exception::class)
override fun configure(http: HttpSecurity) {
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
http.addFilterAfter(secretAuthenticationFilter, UsernamePasswordAuthenticationFilter::class.java)
http
.authorizeRequests()
.antMatchers("/oauth_login")
.permitAll()
.antMatchers("/accounts/password")
.permitAll()
.anyRequest()
.authenticated()
.permitAll()
.and()
.logout()
.logoutUrl("/logoutconfirm")
.logoutSuccessUrl("/oauth_login")
.invalidateHttpSession(true)
.and()
.oauth2Login().loginPage("/oauth_login")
.authorizationEndpoint()
.baseUri("/oauth2/authorize-client")
.authorizationRequestRepository(authorizationRequestRepository())
.authorizationRequestResolver(CustomAuthorizationRequestResolver(inMemoryClientRegistrationRepository, "/oauth2/authorize-client"))
.and()
.tokenEndpoint()
.accessTokenResponseClient(accessTokenResponseClient())
.and()
.defaultSuccessUrl("/loginSuccess")
.failureUrl("/loginFailure")
.addObjectPostProcessor(object : ObjectPostProcessor<Any> {
override fun <O : Any> postProcess(obj: O) = when (obj) {
is OAuth2LoginAuthenticationProvider -> CustomOAuth2LoginAuthenticationProvider(obj) as O
is LoginUrlAuthenticationEntryPoint -> customizeLoginUrlAuthenticationEntryPoint(obj) as O
else -> obj
}
})
}
这是我要添加的 ResourceServerConfig:
@Configuration
@EnableResourceServer
@Order(2)
class ResourceServerConfig(
private val defaultTokenServices: DefaultTokenServices
) : ResourceServerConfigurerAdapter() {
override fun configure(config: ResourceServerSecurityConfigurer) {
config.tokenServices(tokenServices())
}
override fun configure(http: HttpSecurity) {
http.authorizeRequests().anyRequest().authenticated()
}
fun tokenStore() = JwtTokenStore(accessTokenConverter())
fun accessTokenConverter(): JwtAccessTokenConverter {
val converter = object : JwtAccessTokenConverter() {
override fun decode(token: String) = if (token.isCorrectJwtToken(token)) {
super.decode(token)
} else {
mapOf()
}
}
val keyStoreKeyFactory = KeyStoreKeyFactory(ClassPathResource("mykeys.jks"),
"mykeys".toCharArray())
converter.setKeyPair(keyStoreKeyFactory.getKeyPair("mykeys"))
return converter
}
fun tokenServices() = DefaultTokenServices().apply {
setTokenStore(tokenStore())
setSupportRefreshToken(true)
}
这是我希望能够使用有效令牌访问的安全端点:
@PreAuthorize("hasAuthority('ROLE_USER')")
@PostMapping("/accounts/password")
fun updatePassword(@RequestBody newPassword: JsonWrappedValue<String>): Boolean {
// Update password
}
解决方案
我找到了解决我的问题的方法。我将所有配置合并到一个文件中,因此安全配置看起来像这样
@EnableAuthorizationServer
@EnableResourceServer
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@PropertySource("application.properties")
class SecurityConfig(
private val accountRepository: AccountRepository,
private val userDetailsService: CustomUserDetailsService,
private val inMemoryClientRegistrationRepository: InMemoryClientRegistrationRepository,
private val secretAuthenticationFilter: SecretAuthenticationFilter
) : AuthorizationServerConfigurer, ResourceServerConfigurer, WebSecurityConfigurerAdapter()
这使我最终能够使用令牌到达终点,但破坏了我的社交登录。然后我不得不修复该configure(http: HttpSecurity)
方法,因为 ResourceServerConfig 的默认实现SessionCreationPolicy
将SessionCreationPolicy.Never
.
这导致我的社交登录被破坏,因为包含redirectUri等的请求参数无法恢复。添加后
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
到configure(http: HTTPSecurity)
完整的配置效果很好。
推荐阅读
- javascript - 使用 JavaScript 隐藏单选按钮的文本
- oracle - Jenkins 容器:Groovy 脚本因 jbdc 异常而失败
- javascript - 无法从模式中的建议列表中带来
- excel - 尝试分配单元格值,但不断提醒“类型不匹配”
- arrays - 使用函数复制数组
- javascript - 在 GeoServer 上发布 OpenLayers VectorTiles
- elasticsearch - 布尔查询中的不同分数函数
- chart.js - Chart.js 按月\年分组数据
- javascript - 如何计算多个航点之间的航点?
- c# - 以安全的方式在企业应用程序中运行 multipe Task<>