У меня есть загрузочное приложение Spring с spring-security-oauth2-autoconfigure.Сервер ресурсов и сервер авторизации работают в одном приложении.
В приложении есть служба сведений о пользователе, которая глобально настраивается через WebSecurityConfiguration.Он используется для аутентификации владельца ресурсов.
Я настроил сервер авторизации для аутентификации клиентов, используя хранилище в памяти, например:
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("devglan-client")
.secret("$2a$04$e/c1/RfsWuThaWFCrcCuJeoyvwCV0URN/6Pn9ZFlrtIWaU/vj/BfG")
.authorizedGrantTypes("implicit","refresh_token", "password", "authorization_code")
.scopes("read write trust");
}
Проблема:
Когда я пытаюсь получить код авторизации, используя конечную точку авторизации GET, Spring Security пытается аутентифицировать клиент приложения, используя службу сведений о пользователе.
Я включаю в запрос заголовок авторизации HTTP с опцией Basic, который содержит учетные данные cliend_id: client_secret.
GET /oauth/authorize?
response_type=code&client_id=bpclient&scope=read HTTP/1.1
Host: localhost:8080
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Authorization: Basic ZGV2Z2xhbi1jbGllbnQ6MTIzNDU2
Cache-Control: no-cache
Postman-Token: 77dd0129-bb86-d039-d252-8e7d483092f2
Я отладил код и подтвердил, что DaoAuthenticationProvider пытался получить клиент приложенияучетные данные, используя службу сведений о пользователе.
Вопрос
Почему Spring OAuth использует службу сведений о пользователе для проверки подлинности клиентов приложения в потоке авторизации oauth, а не в конфигурации в памяти?
Мой код
Pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>2.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
Приложение Main
@SpringBootApplication()
@EnableAutoConfiguration
public class Application extends RepositoryRestConfigurerAdapter{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Конфигурация сервера авторизации:
@Configuration
@EnableAuthorizationServer
public class ServidorAutorizacaoOAuthConfiguracao extends AuthorizationServerConfigurerAdapter {
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("devglan-client")
.secret("$2a$04$e/c1/RfsWuThaWFCrcCuJeoyvwCV0URN/6Pn9ZFlrtIWaU/vj/BfG")
.authorizedGrantTypes("implicit","refresh_token", "password", "authorization_code")
.scopes("read write trust");
}
}
WebSecurityКонфигурация:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class SegurancaConfiguracao extends WebSecurityConfigurerAdapter{
@Autowired
private UsuarioServico usuarioServico;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(this.usuarioServico).passwordEncoder(encoder());
}
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
Конфигурация сервера ресурсов:
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ServidorRecursoOAuthConfiguracao extends
ResourceServerConfigurerAdapter {
public void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/api/**").authenticated()
.antMatchers("/oauth2/authorization/google", "/login/oauth2/code/google", "/login").permitAll()
.antMatchers("/oauth/authorize").permitAll()
.anyRequest().permitAll()
.and()
.formLogin()
.and()
.oauth2Login()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}