资源服务器配置
- 添加依赖:在
build.gradle.kts
文件中添加 Spring Security OAuth2 资源服务器依赖。
implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server")
- 配置资源服务器:在
application.yml
文件中配置资源服务器相关信息,如令牌的验证端点。
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: http://localhost:8080/auth/realms/demo
- 启用资源服务器:在配置类中使用
@EnableResourceServer
注解启用资源服务器。
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter
@Configuration
@EnableResourceServer
class ResourceServerConfig : ResourceServerConfigurerAdapter() {
override fun configure(http: HttpSecurity) {
http.authorizeRequests()
.antMatchers("/api/**").authenticated()
.anyRequest().permitAll()
}
}
授权服务器配置
- 添加依赖:在
build.gradle.kts
文件中添加 Spring Security OAuth2 授权服务器依赖。
implementation("org.springframework.boot:spring-boot-starter-oauth2-authorization-server")
- 配置授权服务器:创建一个配置类,使用
@EnableAuthorizationServer
注解启用授权服务器,并配置客户端详情、令牌存储等。
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer
import org.springframework.security.oauth2.provider.token.TokenStore
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore
@Configuration
@EnableAuthorizationServer
class AuthorizationServerConfig : AuthorizationServerConfigurerAdapter() {
@Autowired
lateinit var authenticationManager: AuthenticationManager
@Bean
fun passwordEncoder(): PasswordEncoder = BCryptPasswordEncoder()
@Bean
fun tokenStore(): TokenStore = InMemoryTokenStore()
override fun configure(clients: ClientDetailsServiceConfigurer) {
clients.inMemory()
.withClient("clientId")
.secret(passwordEncoder().encode("clientSecret"))
.authorizedGrantTypes("authorization_code", "refresh_token")
.scopes("read", "write")
.redirectUris("http://localhost:8081/login/oauth2/code/demo")
}
override fun configure(endpoints: AuthorizationServerEndpointsConfigurer) {
endpoints.authenticationManager(authenticationManager)
.tokenStore(tokenStore())
}
}
Kotlin 中处理令牌验证、刷新等操作
- 令牌验证:Spring Security OAuth2 资源服务器会自动验证令牌。当请求到达资源服务器时,它会根据配置的
issuer-uri
等信息验证令牌的合法性。如果令牌无效,会返回相应的错误响应。
- 令牌刷新:客户端可以通过发送带有刷新令牌的请求到授权服务器来获取新的访问令牌。在 Kotlin 中,可以使用
RestTemplate
或 WebClient
发送刷新令牌请求。
import org.springframework.http.HttpEntity
import org.springframework.http.HttpHeaders
import org.springframework.http.MediaType
import org.springframework.web.client.RestTemplate
val restTemplate = RestTemplate()
val headers = HttpHeaders()
headers.contentType = MediaType.APPLICATION_FORM_URLENCODED
val body = "grant_type=refresh_token&refresh_token=$refreshToken&client_id=clientId&client_secret=clientSecret"
val entity = HttpEntity(body, headers)
val response = restTemplate.postForObject("http://localhost:8080/oauth/token", entity, String::class.java)
可能遇到的安全风险及应对措施
- 令牌泄露风险
- 风险:如果访问令牌或刷新令牌泄露,攻击者可以使用这些令牌访问受保护的资源。
- 应对措施:使用 HTTPS 协议传输令牌,确保令牌在传输过程中加密;设置合理的令牌过期时间,减少令牌暴露的窗口;对令牌进行加密存储,尤其是刷新令牌。
- 授权服务器安全风险
- 风险:授权服务器可能成为攻击目标,如果被攻破,攻击者可以颁发恶意令牌。
- 应对措施:对授权服务器进行严格的访问控制,只允许受信任的客户端访问;使用强密码和加密技术保护授权服务器的配置和存储的客户端信息;定期更新授权服务器的依赖库,修复已知的安全漏洞。
- 重定向 URI 篡改风险
- 风险:攻击者可能篡改授权码模式中的重定向 URI,将用户重定向到恶意站点获取授权码。
- 应对措施:在授权服务器中严格验证客户端注册的重定向 URI,确保请求中的重定向 URI 与注册的一致;对重定向 URI 进行白名单管理。