#spring-security #oauth-2.0
#spring-безопасность #oauth-2.0
Вопрос:
Я внедряю авторизацию OAuth2 с помощью Spring Boot. У меня уже есть сервер авторизации и сервер ресурсов, теперь я хочу получить доступ к ресурсам с сервера ресурсов, используя client_credentials
тип предоставления.
Я немного смущен этим, потому что на сервере ресурсов я должен добавить client_id
и client_secret
. Но зачем серверу ресурсов это действительно нужно?
Насколько я понимаю эту концепцию, клиент должен получить от сервера авторизации, используя учетные данные клиента, свой токен доступа. А затем отправьте этот токен доступа на сервер ресурсов без каких-либо учетных данных клиента.
Итак, почему серверу ресурсов также нужны некоторые учетные данные клиента? Сервер ресурсов и клиент — это две отдельные сущности, я не понимаю, почему сервер ресурсов должен знать о client_id
и client_secret
.
Почему токена доступа недостаточно для аутентификации? check_token
конечная точка может возвращать список ресурсов, к которым можно получить доступ с помощью этого токена, и если у клиента есть этот токен, это означает, что он уже аутентифицирован с учетными данными клиента для получения этого токена.
Что, если я хочу получить доступ от нескольких разных клиентов к этому серверу ресурсов?
Конфигурация сервера ресурсов:
@Configuration
@RestController
@EnableWebSecurity
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(final HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/**").authenticated()
.and()
.httpBasic().disable();
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources
.resourceId("translate-service");
}
}
Свойства сервера ресурсов:
security.oauth2.resource.user-info-uri=http://localhost:8090/user
security.oauth2.resource.token-info-uri=http://localhost:8090/oauth/check_token
security.oauth2.client.client-id=XXXX
security.oauth2.client.client-secret=XXXX
Если я не буду устанавливать свойства клиента, Spring выдаст предупреждение:
Обнаружен нулевой идентификатор клиента или секрет клиента. Конечная точка, требующая аутентификации, отклонит запрос с ошибкой 401.
И аутентификация не будет работать.
Может быть, я делаю что-то не так, и есть какое-то решение не предоставлять client_id
на сервере ресурсов?
Ответ №1:
Если вы используете, RemoteTokenServices
ваш сервер ресурсов также является дополнительным клиентом сервера авторизации, см. Руководство для разработчиков OAuth 2:
Альтернативой является,
RemoteTokenServices
которая представляет собой функции Spring OAuth (не входящие в спецификацию), позволяющие серверам ресурсов декодировать токены через HTTP-ресурс на сервере авторизации (/oauth/check_token
).RemoteTokenServices
удобны, если на серверах ресурсов нет большого объема трафика (каждый запрос должен быть проверен сервером авторизации), или если вы можете позволить себе кэшировать результаты. Чтобы использовать/oauth/check_token
конечную точку, вам нужно предоставить ее, изменив ее правило доступа (по умолчанию «denyAll()») вAuthorizationServerSecurityConfigurer
, например
@Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { oauthServer.tokenKeyAccess("isAnonymous() || hasAuthority('ROLE_TRUSTED_CLIENT')").checkTokenAccess( "hasAuthority('ROLE_TRUSTED_CLIENT')"); }
В этом примере мы настраиваем как
/oauth/check_token
конечную точку, так и конечную точку/oauth/token_key
(чтобы доверенные ресурсы могли получить открытый ключ для проверки JWT). Эти две конечные точки защищены базовой аутентификацией HTTP с использованием учетных данных клиента.
2.4 Как настроить конечную точку информации о токене
Конечная точка информации о токене, также иногда называемая конечной точкой самоанализа, вероятно, требует какой-либо аутентификации клиента, либо базовой, либо на предъявителя. Вообще говоря, токена-носителя в
SecurityContext
недостаточно, поскольку он привязан к пользователю. Вместо этого вам нужно будет указать учетные данные, которые представляют этого клиента, например:spring: security: oauth2: client: clientId: client-id clientSecret: client-secret resource: tokenInfoUri: https://issuer/oauth2/check_token
По умолчанию для аутентификации в конечной точке token info будет использоваться базовая аутентификация с использованием настроенных учетных данных.