nordeus/crowd-user-bundle

CrowdUserBundle 是一个用于从 Atlassian Crowd 获取用户并进行验证的 Symfony 扩展包。

安装次数: 1,977

依赖: 0

建议者: 0

安全: 0

星标: 3

关注者: 10

分支: 2

开放问题: 1

类型:symfony-bundle

v2.1 2019-05-17 14:08 UTC

This package is auto-updated.

Last update: 2024-09-20 20:05:51 UTC


README

CrowdUserBundle 是一个用于从 Atlassian Crowd 获取用户并进行验证的 Symfony 扩展包。

安装和配置

1. 使用 composer 克隆此仓库

在项目根目录执行以下操作

composer require nordeus/crowd-user-bundle

如果您使用 Symfony Flex

该扩展包已为您自动注册和配置!跳到步骤 4。

2. 在内核中启用扩展包

<?php
// config/bundles.php
return [
	// ...
	Nordeus\CrowdUserBundle\NordeusCrowdUserBundle::class => ['all' => true],
];

3. 导入 CrowdUserBundle 路由文件

# config/routes/nordeus_crowd_user.yaml
nordeus_crowd_user:
    resource: "@NordeusCrowdUserBundle/Resources/config/routing.yaml"

如果您打算手动覆盖一些 CrowdUserBundle 的路由(见步骤 6),请确保在您的扩展包配置之后包含此文件。

4. 配置参数

以下是需要设置的参数

# config/packages/nordeus_crowd_user.yaml
nordeus_crowd_user:
    crowd_application_name: crowd_application_name
    crowd_application_password: crowd_application_password
    crowd_service_url: http://crowd.your_domain.com:8095
    sso_cookie_domain: your_domain.com
    roles_to_groups:
        ROLE_USER: [ users ]
        ROLE_ADMIN: [ admins, superadmins ]

通过提供每个 Symfony 角色的 Crowd 组列表来设置您的 roles_to_groups 映射,以便那些组中的用户应该接收这些角色。

还有可选参数,它们有默认值。这些参数包括

# config/packages/nordeus_crowd_user.yaml
nordeus_crowd_user:
    # ...
    user_class: Nordeus\CrowdUserBundle\Security\User\CrowdUser
    sso_cookie_name: crowd.token_key
    service_uri: /crowd/rest/usermanagement/1/
    curl_timeout: 2
    connection_retries: 2
    user_refresh_time: 600 # seconds

如果您想扩展 CrowdUser,请使用 user_class 参数并设置您的用户类名称作为值。

5. 配置您应用程序的安全性

# config/packages/security.yaml
security:
    role_hierarchy:
        ROLE_ADMIN: ROLE_USER

    providers:
        crowd_provider:
            id: crowd.user_provider

    firewalls:
        main:
            pattern: ^/
            crowd_form_login:
                login_path: nordeus_crowd_user_login
                check_path: nordeus_crowd_user_login_check
                default_target_path: /
            crowd_sso: true
            logout:
                path: nordeus_crowd_user_logout
            anonymous: ~
            access_denied_handler: crowd.access_denied_handler

    access_control:
        - { path: ^/(_(profiler|wdt)|img|css|js|login), role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/, role: ROLE_USER }

default_target_path 键是可选的,可以重新配置,它是在成功登录后用户将被重定向的路径。

access_denied_handler 键是可选的,它将导致 拒绝访问 错误重定向到带有错误消息的登录页面,而不是中断请求。

6. (可选)覆盖一些 CrowdUserBundle 的功能

假设您想覆盖控制器(更改一些业务逻辑)或资源(模板、路由等)来自 CrowdUserBundle。有两种可能的方案

A. 扩展包继承

设置后,您的扩展包中任何匹配的文件将自动覆盖 CrowdUserBundle 中的文件。请阅读设置扩展包继承的基础知识并遵循此处的说明。

B. 手动重新路由

在您的扩展包中,定义一个使用现有 CrowdUserBundle 路径的路由,只需将其目标设置为您的某个操作即可。如果您需要原始功能的一些部分,请扩展原始控制器/模板。

7. 清除 Symfony 缓存

php bin/console cache:clear

待办事项

  • 在测试环境中模拟或禁用身份验证

说明

Symfony 身份验证基于以下概念

在安全部分(app/config/security.yaml)中,您必须定义一个防火墙。最常见的情况是只定义一个防火墙 - main 防火墙。以下是一个示例

# app/config/security.yaml
security:
    firewalls:
        main:
            pattern: ^/
            crowd_form_login:
                login_path: nordeus_crowd_user_login
                check_path: nordeus_crowd_user_login_check
                default_target_path: /
            crowd_sso: true
            logout:
                path: nordeus_crowd_user_logout
            anonymous: ~
            access_denied_handler: crowd.access_denied_handler

防火墙实现的工作方式如下:防火墙监听 onKernelRequest 事件。当事件被触发时,它使用防火墙映射来确定将使用哪个防火墙来处理事件。防火墙映射返回一个与请求路径匹配的模式。在我们的情况下,我们只定义了一个防火墙,它匹配每个路径(“pattern: ^/”),因此我们的 main 防火墙负责在每个请求上验证用户。

main 防火墙有许多身份验证监听器,可以验证用户。因此,在内核请求时,它会遍历所有监听器,传递一个事件对象给它们的 handle 方法。如果有任何监听器返回一个 Response,它将中断循环并返回该响应。让我们列出这些监听器。

  • Channel Listener
    • 负责切换 HTTP 协议
  • Context Listener
    • 检查是否存在会话,如果会话中存在认证令牌(如果会话中存在认证令牌),则从会话中获取认证令牌
    • 从认证令牌中获取用户,然后通过调用UserProvider的refreshUser方法刷新用户;之后将用户保存到认证令牌中,并将令牌存储在上下文中。
    • 监听onKernelResponse事件 - 目的是在上下文中获取最终的认证令牌(如果它仍然存在)并将其存储回会话。
  • “自定义监听器” - 将在后面解释,那些是
    • pre_auth 监听器
    • form 监听器
    • http 监听器
    • remember-me 监听器
  • 注销监听器 - 如果在配置中启用,则为活动状态("logout: " ... )
    • 检查是否请求了注销路径。如果是,调用其注销处理器(可能删除一些Cookie),将上下文设置为null,并将响应返回给防火墙,防火墙中断进一步认证。
  • 匿名监听器 - 仅当在配置中启用时才活动 ("anonymous: ~")
    • 此时,监听器有机会生成一个认证令牌。
    • 如果没有人这样做(上下文中设置为null),则生成匿名令牌并将其设置在上下文中。
  • 访问监听器
    • 检查令牌是否存在于上下文中(如果匿名监听器不活动,可能被设置为null)
    • 检查令牌是否已认证,如果没有,则尝试通过将令牌传递给AuthenticationManager来认证令牌。

“自定义监听器”是其他认证监听器可以附加的地方。在此实现中,有两个监听器:CrowdLoginAuthenticationListener和CrowdSSOAuthenticationListener。注册认证监听器的过程是通过实现SecurityFactoryInterface的工厂完成的(DependencyInjection/Security/Factory)。此接口表示您必须定义

  • 位置,其中监听器将被放置在“自定义监听器”部分,它可以是以下值之一:pre_authformhttpremember-me
  • key,用于识别您的工厂。在配置(上面)中,我们通过在防火墙部分中列出它们来启用这些工厂(crowd_form_logincrowd-sso)。
  • create方法,它应该创建入口点认证监听器认证提供者
  • addConfiguration用于定义工厂使用的参数。在上面的示例中,crowd_form_login工厂使用login_pathcheck_path

现在,我们已经将监听器附加到防火墙,认证流程如下:认证监听器应从请求中获取一些数据(登录监听器从登录表单中获取用户名和密码,SSO监听器获取SSOCookieToken),然后监听器创建CrowdAuthenticationToken并用数据填充它,监听器调用令牌的认证。CrowdAuthenticationProvider接收认证令牌,从UserProvider中获取CrowdUser(使用认证令牌中提供的数据),将CrowdUser存储在认证令牌中。监听器再次获取认证令牌,然后将其标记为已认证并存储在上下文中。

登录是如何完成的:Symfony已经提供了AbstractAuthenticationListener,CrowdLoginAuthenticationListener扩展了它。AbstractAuthenticationListener执行一些检查(例如,检查请求的路径是否是登录页面的路径),然后调用CrowdLoginAuthenticationListener中的attemptAuthentication方法。该方法应返回CrowdAuthenticationProvider提供的CrowdAuthenticatedToken,然后AbstractAuthenticationListener调用SuccessHandler。因此,CrowdLoginAuthenticationListener获取用户名和密码,将它们发送到CrowdAuthenticationToken;CrowdLoginSuccessHandler在响应中设置一个SSO Crowd cookie;

现在,当用户登录时,认证令牌将存储在会话中。在每次请求中,登录监听器不做任何事情,除非请求路径与登录路径匹配。SSO监听器读取SSO Crowd cookie,因为会话中已存在认证令牌,所以它会在令牌上设置认证标志并返回它,无需在每次请求时从Crowd服务器获取用户。匿名监听器在上下文中找到认证令牌并不做任何事情。访问监听器检查认证令牌是否已认证——如果是,就完成了。用户保持认证状态。

如上所述,ContextListener在每次请求都会调用UserProvider的refreshUser方法,这就不必在每次请求时从Crowd获取用户,UserProvider仅在定义的参数“某些时间”后刷新用户。

如果用户请求注销,注销监听器激活,遍历所有的注销处理程序并调用它们的注销方法。CrowdSSOLogoutHandler删除SSO Crowd cookie。