Я применил поток владельца ресурсов с помощью spring oauth2 на основе приложения образца spring sparklr и нескольких образцов, которые я нашел в Интернете. Я протестировал часть запроса токена с завитком, подобным этому, чтобы предоставить как клиентские, так и пользовательские учетные данные:
curl -v --data "username=user1&password=user1&client_id=client1&client_secret=client1&grant_type=password" -X POST "http://localhost:8080/samplerestspringoauth2/oauth/token"
и он работает правильно, однако я сделал следующее замечание:
Хотя в соответствии с примерами, которые я видел, я использую фильтр BasicAuthentication, это не используется в процессе безопасности. Поскольку в запросе токена нет заголовка проверки подлинности, фильтр BasicAuthentication просто пропускает выполнение каких-либо проверок. ClientCredentialsTokenEndpointFilter и сервер аутентификации являются единственными, которые выполняют проверки безопасности во время запроса маркера. Заметив это и проверив его с помощью отладки, я попытался полностью удалить следующую часть:
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
из конфигурации. Но потом я получил предупреждение:
"Нет аутентификацииEntryPoint может быть установлена. у вас есть механизм входа, настроенный через пространство имен (например, form-login) или указать пользовательский AuthenticationEntryPoint с атрибут" entry-point-ref".
В качестве следующего шага я добавил точку входа-ref = "clientAuthenticationEntryPoint в пространстве имен http и избавился от предупреждения. Я протестировал приложение и проиграл правильно.
Однако, помимо вышесказанного, я также сделал следующее наблюдение во время отладки: ClientCredentialsTokenEndpointFilter содержит свою собственную точку входа OAuth2AuthenticationEntryPoint внутри частной переменной и использует это при сбое из-за неправильных учетных данных клиента. Поэтому не имеет значения, какую точку входа я указываю либо в базовом фильтре, либо в пространстве имен http. В конце ClientCredentialsTokenEndpointFilter будет использовать свой собственный OAuth2AuthenticationEntryPoint. Подводя итоги, мои выводы выглядят следующим образом:
- Основной фильтр не используется и может быть удален, если мы укажем конечной точки в пространстве имен HTTP.
- Указание либо основного фильтра или конечной точки в пространстве имен http требуется только для компилятор, чтобы остановить предупреждение. Они не имеют практического применения, и используемая конечная точка жестко закодирована внутри ClientCredentialsTokenEndpointFilter.
Ниже я поставил конфигурацию http и endpoint для запроса маркера для вашей справки. Я пропущу остальную конфигурацию, чтобы прочитать сообщение легко:
<http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<custom-filter ref="clientCredentialsTokenEndpointFilter"
before="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="springsec/client" />
<property name="typeName" value="Basic" />
</bean>
Я также предполагаю, что та же проблема возникает и в исходном приложении sparklr (который является spring oauth2 sample app) для запроса токена, который очень похож. Это можно найти в https://github.com/spring-projects/spring-security-oauth/blob/master/samples/oauth2/sparklr/src/main/webapp/WEB-INF/spring-servlet.xml, а соответствующая часть ниже:
<http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/**" method="GET" access="ROLE_DENY" />
<intercept-url pattern="/**" method="PUT" access="ROLE_DENY" />
<intercept-url pattern="/**" method="DELETE" access="ROLE_DENY" />
<intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<!-- include this only if you need to authenticate clients via request
parameters -->
<custom-filter ref="clientCredentialsTokenEndpointFilter"
after="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
Я ожидал бы spring oauth2 более разумно взаимодействовать с безопасностью spring вместо того, чтобы ставить ненужную и вводящую в заблуждение конфигурацию, и это заставляет меня думать, что я, возможно, что-то пропустил. Поскольку безопасность - это чувствительный аспект, я хотел бы поделиться этим с вами и спросить, правильно ли было мое заключение.