【发布时间】:2021-06-24 19:29:33
【问题描述】:
我有一个 Spring Boot Auth 微服务。它使用 Oauth2 spring cloud starter 依赖项 deprecated nowadays。
buildscript {
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:2.1.9.RELEASE"
}
}
dependencies {
implementation "org.springframework.boot:spring-boot-starter-actuator"
implementation "org.springframework.boot:spring-boot-starter-data-jpa"
implementation "org.springframework.boot:spring-boot-starter-web"
implementation "org.springframework.cloud:spring-cloud-starter-oauth2:2.1.5.RELEASE"
}
它还有一个自定义的user_details 表。 JPA 类正在实现UserDetails。我还为UserDetailsService 提供了一个实现,它在我的自定义表中查找用户。
OAuth 配置相当前卫:
AuthorizationServerConfiguration - 配置 oauth 的位置:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableAuthorizationServer
class AuthorizationServerConfiguration : AuthorizationServerConfigurerAdapter() {
@Autowired private lateinit var authenticationManager: AuthenticationManager
@Autowired private lateinit var dataSource: DataSource
@Autowired
@Qualifier("customUserDetailsService")
internal lateinit var userDetailsService: UserDetailsService
@Autowired
private lateinit var passwordEncoder: BCryptPasswordEncoder
override fun configure(endpoints: AuthorizationServerEndpointsConfigurer) {
endpoints
.tokenStore(JdbcTokenStore(dataSource))
.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService)
}
override fun configure(clients: ClientDetailsServiceConfigurer) {
// This one is used in conjunction with oauth_client_details. So like there's one app client and a few backend clients.
clients.jdbc(dataSource)
}
override fun configure(oauthServer: AuthorizationServerSecurityConfigurer) {
oauthServer.passwordEncoder(passwordEncoder)
}
}
WebSecurityConfiguration - 上面的类需要:
@Configuration
class WebSecurityConfiguration : WebSecurityConfigurerAdapter() {
@Bean // We need this as a Bean. Otherwise the entire OAuth service won't work.
override fun authenticationManagerBean(): AuthenticationManager {
return super.authenticationManagerBean()
}
override fun configure(http: HttpSecurity) {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
}
}
ResourceServerConfiguration - 配置端点访问:
@Configuration
@EnableResourceServer
class ResourceServerConfiguration : ResourceServerConfigurerAdapter() {
override fun configure(http: HttpSecurity) {
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().cors().disable().csrf().disable()
.authorizeRequests()
.antMatchers("/oauth/token").authenticated()
.antMatchers("/oauth/user/**").authenticated()
.antMatchers("/oauth/custom_end_points/**").hasAuthority("my-authority")
// Deny everything else.
.anyRequest().denyAll()
}
}
这几行给了我很多。
- 用户信息端点(由微服务使用)
- 移动前端等客户端可以使用以下方式进行身份验证:
POST oauth/token并提供grant_type=password以及用户名和密码。 - 服务器可以使用 'oauth/authorize' 进行授权
- 还可以使用不同权限的基本身份验证支持,因为我可以将用户名 + 密码填写到
oauth_client_details表中:
select client_id, access_token_validity, authorities, authorized_grant_types, refresh_token_validity, scope from oauth_client_details;
client_id | access_token_validity | authorities | authorized_grant_types | refresh_token_validity | scope
-------------------+-----------------------+-------------------------------+-------------------------------------------+------------------------+---------
backend | 864000 | mail,push,app-register | mail,push,client_credentials | 864000 | backend
app | 864000 | grant | client_credentials,password,refresh_token | 0 | app
如果还没有 oauth 令牌,应用程序会使用它。
其他微服务也使用它来保护它们的端点——例如在这个例子中:
@Configuration @EnableResourceServer class ResourceServerConfig : ResourceServerConfigurerAdapter() {
override fun configure(http: HttpSecurity) {
http.authorizeRequests()
// Coach.
.antMatchers("/api/my-api/**").hasRole("my-role")
.antMatchers("/registration/**").hasAuthority("my-authority")
}
}
他们的设置很简单:
security.oauth2.client.accessTokenUri=http://localhost:20200/oauth/token
security.oauth2.client.userAuthorizationUri=http://localhost:20200/oauth/authorize
security.oauth2.resource.userInfoUri=http://localhost:20200/oauth/user/me
security.oauth2.client.clientId=coach_client
security.oauth2.client.clientSecret=coach_client
前三个属性只是转到我的授权服务器。最后两个属性是我也插入到oauth_client_details 表中的实际用户名+密码。当我的微服务想要与它使用的另一个微服务通信时:
val details = ClientCredentialsResourceDetails()
details.clientId = "" // Values from the properties file.
details.clientSecret = "" // Values from the properties file.
details.accessTokenUri = "" // Values from the properties file.
val template = OAuth2RestTemplate(details)
template.exchange(...)
现在我的问题是 - 我怎样才能通过 Spring Security 的内置支持使用 Spring Boot 获得所有这些?我想从已弃用的软件包中迁移出来并保留所有令牌,以便用户在之后仍然登录。
【问题讨论】:
标签: spring spring-boot oauth-2.0 oauth