Поток аутентификации пользователя с помощью FOSUserBundle + FOSOAuthServerBundle
Я работал над настройкой трио FOSUserBundle/RestBundle/OAuthServerBundle, чтобы создать безголовый бэкэнд, который затем мог бы разместить отдельный внешний интерфейс и, в конечном итоге, расширить до мобильного и возможного доступа стороннего API. У меня есть общая конфигурация на основе различных доступных ресурсов и инструкций, и я могу сгенерировать токен доступа, используя учетные данные клиента.
Приложение, к которому это добавляется, является существующим, которое использует стандартный Symfony/Twig для взаимодействия между интерфейсом и бэкендом и использует FOSUserBundle для аутентификации.
У меня есть две проблемы, связанные с потоком аутентификации.
- Я хочу, чтобы пользователь мог получить доступ к некоторым частям API без аутентификации после уровня клиента, а некоторые части потребуют аутентификации на уровне пользователя, чтобы убедиться, что они владеют запрошенными ресурсами. Я не нахожу способ сделать это. Я нашел посты, в которых говорилось о возможности, но ничего не давало указаний о том, как этого достичь. Я полагаю, что мне нужно будет проверить на уровне контроллера соответствующий доступ, возможно, с использованием пользовательских избирателей, поскольку проверка для IS_AUTHENTICATED_FULLY возвращается как истинная после простой аутентификации с клиентом. Я хочу иметь возможность программной аутентификации пользователя, минуя форму входа в систему пользовательского интерфейса - это может быть просто переопределение контроллера входа FOSUserBundle, но я не уверен.
- Мне нужно либо создать клиент без истечения срока действия токена доступа, либо найти способ реализовать токен обновления. Я действительно не понимаю, почему мое собственное приложение должно обновлять токен, но если это стандартный способ сделать это, я согласен со следующими характеристиками.
Ниже приведен некоторый соответствующий код, хотя по большому счету код представляет собой стандартную коробку, скопированную из руководства по установке FOSOAuthServer.
security.yml
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
firewalls:
oauth_token:
pattern: ^/oauth/v2/token
security: false
rest:
pattern: ^/rest(?!/doc)
fos_oauth: true
stateless: true
anonymous: false
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
success_handler: security.authentication.success_handler
use_referer: true
logout: true
anonymous: true
access_control:
- { path: ^/rest, roles: [ IS_AUTHENTICATED_FULLY ] }
фрагмент config.yml
fos_user:
db_driver: orm
firewall_name: main
user_class: AppBundle\Entity\User
registration:
form:
type: AppBundle\Form\Type\RegistrationFormType
profile:
form:
type: user_profile
fos_oauth_server:
db_driver: orm
client_class: AppBundle\Entity\Client
access_token_class: AppBundle\Entity\AccessToken
refresh_token_class: AppBundle\Entity\RefreshToken
auth_code_class: AppBundle\Entity\AuthCode
service:
user_provider: fos_user.user_provider.username_email
options:
supported_scopes: user
fos_rest:
view:
view_response_listener: force
formats:
json: true
templating_formats:
html: true
mime_types:
json: ['application/json', 'application/json;version=1.0', 'application/json;version=1.1']
jpg: ['image/jpeg']
png: ['image/png']
body_listener: true
param_fetcher_listener: true
allowed_methods_listener: true
format_listener:
rules:
- { path: ^/, priorities: [html, json], fallback_format: json, prefer_extension: false }
1 ответ
AD 1) Я решил вашу проблему с двумя брандмауэрами в security.yml
, Так как Symfony ищет первый матч в security.yml
Я установил первый брандмауэр, чтобы позволить анонимным пользователям:
api_anonym_area:
pattern: (^/api/forgotten-password/.*)
stateless: true
fos_oauth: true
anonymous: true
Я ловлю URL с помощью регулярных выражений и даю anonymous: true
В качестве второго брандмауэра у меня есть регулярное выражение, которое ловит все
api_auth_area:
pattern: ^/
fos_oauth: true
stateless: true
anonymous: false
Так что в вашем случае, если вы хотите, чтобы анонимные пользователи попали в / rest / doc, поставьте перед собой firewall:rest
что-то вроде этого:
rest_doc:
pattern: ^/rest/doc
fos_oauth: true
stateless: true
anonymous: true
AD 2) Не рекомендуется использовать токен неограниченного доступа, но вы можете сделать это в config.yml
установив большое целое число access_token_lifetime
:
fos_oauth_server:
service:
options:
access_token_lifetime: #number in seconds#
Чтобы войти с помощью токена обновления просто
/oauth/v2/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
его в FOSOAuthServerBundle из коробки