l3/cas-bundle

PHPCas 包装器,支持 Symfony2, Symfony3, Symfony4, Symfony5

安装数: 36,407

依赖关系: 0

建议者: 0

安全: 0

星标: 33

关注者: 4

分支: 10

开放问题: 6

类型:symfony-bundle

1.1.14 2023-08-06 09:25 UTC

This package is auto-updated.

Last update: 2024-09-06 12:24:47 UTC


README

Symfony Cas Bundle

此包是针对经典 jasig/phpCAS 库的依赖性包装器。

支持单点注销(BeSimpleSSoBundle 不支持)。

(对于 Symfony 6,请参考 l3/cas-guard-bundle 包。)

安装

使用以下命令安装 Bundle:

composer require l3/cas-bundle:~1.0

Symfony 的 Kernel 中 Bundle 的声明

对于 Symfony2 或 Symfony3,在 app/AppKernel.php 中添加 Bundle

<?php
// app/AppKernel.php

// ...
class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            // ...

            new L3\Bundle\CasBundle\L3CasBundle(),
        );

        // ...
    }

    // ...
}

对于 Symfony4 和 Symfony5,在 config/bundles.php 中添加 Bundle(如果行不存在)

<?php

return [
    ...
    L3\Bundle\CasBundle\L3CasBundle::class => ['all' => true],
    ...
];

Bundle 配置

对于 Symfony2 或 Symfony3,在您的配置文件(parameters.yml 和 parameters.yml.dist)中添加 l3_cas 参数

l3_cas:
    host: cas-test.univ-lille3.fr                       # Cas Server
    path: ~                                             # App path if not in root (eg. cas.test.com/cas)
    port: 443                                           # Server port
    ca: false                                           # SSL Certificate
    handleLogoutRequest: true                           # Single sign out activation (default: false)
    casLogoutTarget: https://ent-test.univ-lille3.fr    # Redirect path after logout
    force: true                                         # Allows cas check mode and not force, user : __NO_USER__ if not connected (If force false, Single sign out cant work).
    gateway: true					# Gateway mode (for use the mode gateway of the Cas Server) set to false if you use micro-services or apis rest.

对于 Symfony4 和 Symfony5,在您的配置文件(.env 和 .env.dist)中添加变量

...
###> l3/cas-bundle ###
CAS_HOST=cas-test.univ-lille3.fr     # Cas Server
CAS_PATH=~                           # App path if not in root (eg. cas.test.com/cas)
CAS_PORT=443                         # Server port
CAS_CA=false                         # SSL Certificate
CAS_HANDLE_LOGOUT_REQUEST=true       # Single sign out activation (default: false)
CAS_LOGIN_TARGET=https://server.univ-lille3.fr # Redirect path after login (when use anonymous mode)
CAS_LOGOUT_TARGET=https://ent-test.univ-lille3.fr    # Redirect path after logout
CAS_FORCE=true                       # Allows cas check mode and not force, user : __NO_USER__ if not connected (If force false, Single sign out cant work).
CAS_GATEWAY=true		     # Gateway mode (for use the mode gateway of the Cas Server) set to false if you use micro-services or apis rest.
###< l3/cas-bundle ###
...

并在您的 config/services.yml 文件中添加参数(在参数下)

...
parameters:
    cas_login_target: '%env(string:CAS_LOGIN_TARGET)%'
    cas_logout_target: '%env(string:CAS_LOGOUT_TARGET)%'
    cas_host: '%env(string:CAS_HOST)%'
    cas_path: '%env(string:CAS_PATH)%'
    cas_gateway: '%env(bool:CAS_GATEWAY)%'

l3_cas:
    host: '%env(string:CAS_HOST)%'
    path: '%env(string:CAS_PATH)%'
    port: '%env(int:CAS_PORT)%'
    ca: '%env(bool:CAS_CA)%'
    handleLogoutRequest: '%env(bool:CAS_HANDLE_LOGOUT_REQUEST)%'
    casLogoutTarget: '%env(string:CAS_LOGOUT_TARGET)%'
    force: '%env(bool:CAS_FORCE)%'
    gateway: '%env(bool:CAS_GATEWAY)%'
...

安全配置

对于 Symfony2 或 Symfony3 或 Symfony4 或 Symfony5,在 app/config/security.yml 中的安全文件中配置防火墙

security:
    providers:
            # ...


    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt|error)|css|images|js)/
            security: false

        l3_firewall:
            pattern: ^/
            security: true
            cas: true # Activation du CAS

匿名配置

请注意,如果您想使用匿名模式,则 Bundle cas 使用登录 NO_USER,使用以下安全设置

security:
    providers:
        chain_provider:
            chain:
                providers: [in_memory, your_userbundle]
        in_memory:
            memory:
                users:
                    __NO_USER__:
                        password:
                        roles: ROLE_ANON
        your_userbundle:
            id: your_userbundle

在 Symfony4 中,如果您使用 chain_provider,应在 config/packages/security.yaml 中的所有条目(即 l3_firewall 和 main)防火墙(在 security 激活的地方:security: true)上设置提供者名称,如下所示

# config/packages/security.yaml
security:
    providers:
        chain_provider:
            chain:
                providers: [in_memory, your_userbundle]
        in_memory:
            memory:
                users:
                    __NO_USER__:
                        password:
                        roles: ROLE_ANON
        your_userbundle:
            id: your_userbundle

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

        l3_firewall:
            pattern: ^/
            security: true
            cas: true # Activation du CAS
            provider: chain_provider
            
        main:
            pattern: ^/
            security: true
            cas: true # Activation du CAS
            anonymous: true
            provider: chain_provider

然后在 app/config/parameters.yml(对于 Symfony2 或 Symfony3)和 config/services.yaml(对于 Symfony4)中将 force 设置为 false

l3_cas:
    ...
    force: false                                         # Allows cas check mode and not force, user : __NO_USER__ if not connected (If force false, Single sign out cant work).

对于 Symfony2 或 Symfony3,在 app/config/security.yml 中将 default: anonymous

security:
    providers:
            # ...


    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt|error)|css|images|js)/
            security: false

        l3_firewall:
            pattern: ^/
            security: true
            cas: true # Activation du CAS

        default:
            anonymous: ~

对于 Symfony4,在 config/packages/security.yaml 中将 main: anonymous

security:
    providers:
            # ...


    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

        l3_firewall:
            pattern: ^/
            security: true
            cas: true # Activation du CAS

        main:
            anonymous: ~
            pattern: ^/
            security: true
            cas: true # Activation du CAS

对于 Symfony 5,将 anonymous: true 替换为 lazy: true,如下所示

        main:
            pattern: ^/
            security: true
            lazy: true

对于 Symfony2 或 Symfony3,在 app/config/parameters.yml.dist 和 app/config/parameters.yml 下的参数中添加 cas_host、cas_login_target、cas_path 和 cas_gateway(不在 l3_cas 下)

	...
        cas_login_target: https://your_web_path_application.com/
        cas_logout_target: https://your_web_path_application.com/
        cas_host: cas-test.univ-lille3.fr
        cas_path: ~
        cas_gateway: true
	...

对于 Symfony4 和 Symfony5,在 config/services.yaml 下的参数中添加 cas_host 和 cas_login_target(不在 l3_cas 下)

        ...
        cas_login_target: '%env(string:CAS_LOGIN_TARGET)%'
        cas_logout_target: '%env(string:CAS_LOGIN_TARGET)%'
        cas_host: '%env(string:CAS_HOST)%'
        cas_path: '%env(string:CAS_PATH)%'
        cas_gateway: '%env(bool:CAS_GATEWAY)%'
        ...

对于 Symfony 2、Symfony 3 和 Symfony 4,在您的应用程序的 DefaultController 中创建登录路由和强制路由

/**
 * @Route("/login", name="login")
 */
public function loginAction() {
        
	$url = 'https://'.$this->container->getParameter('cas_host') . $this->container->getParameter('cas_path') . '/login?service=';
        $target = $this->container->getParameter('cas_login_target');

        return $this->redirect($url . urlencode($target . '/force'));
}


/**
 * @Route("/force", name="force")
 */
public function forceAction() {

	if ($this->container->getParameter('cas_gateway')) {
        	if (!isset($_SESSION)) {
                	session_start();
        	}

        	session_destroy();
	}

        return $this->redirect($this->generateUrl('homepage'));
}

对于 Symfony 5,在您的应用程序的 DefaultController 中创建登录路由和强制路由

    /**
     * @Route("/login", name="login")
     */
    public function login(Request $request) {
           $url = 'https://'.$this->getParameter('cas_host') . $this->getParameter('cas_path') . '/login?service=';
           $target = $this->getParameter('cas_login_target');
           return $this->redirect($url . urlencode($target . '/force'));
    }
    
    /**
     * @Route("/force", name="force")
     */
    public function force(Request $request) {

            if ($this->getParameter('cas_gateway')) {
                if (!isset($_SESSION)) {
                        session_start();
                }

                session_destroy();
            }

            return $this->redirect($this->generateUrl('index'));
    }

最后,您可以使用 /login 路由调用 cas 登录页面并重定向到您的应用程序,然后您就连接上了 :)

单点注销配置

为了使用单点注销,建议在 Symfony 中禁用 Sessions(这样您将使用 PHP 本地会话)。

# app/config/config.yml (for Symfony2 or Symfony3)
# config/packages/framework.yaml (for Symfony4 and Symfony5)
framework:
    # ...
    session:
        handler_id:  ~
        save_path: ~

信息:此包会与 PHPCas 进行检查,以检测一些 PHPCAS 未完全实现的断开连接请求(有关更多详细信息,请参阅 L3\Bundle\CasBundle\Security\CasListener::checkHandleLogout())

用户提供者

对于 LDAP 用户,您可以使用 LdapUserBundle(分支 ou=people)或 LdapUdlUserBundle(分支 ou=accounts)。您还可以使用仅返回 uid 的简单 UidUserBundle。

您还可以使用 FOSUserBundle...,如下所示://security.yml

    providers:
        chain_provider:
            chain:
                providers: [in_memory, fos_userbundle]
        in_memory:
            memory:
                users:
                    __NO_USER__:
                        password:
                        roles: ROLE_ANON
        fos_userbundle:
            id: fos_user.user_provider.username

注销路由

在 Symfony 2 或 Symfony 3 中,如果您想使用 /logout 路由来调用注销,您可以在您的 routing.yml 文件中添加以下内容:

l3_logout:
    path:     /logout
    defaults: { _controller: L3CasBundle:Logout:logout }

在 Symfony 4 中,您可以在您的 routes.yaml 文件中添加以下内容:

logout:
    path: /logout
    controller: L3\Bundle\CasBundle\Controller\LogoutController::logoutAction

在 Symfony 5 中,您必须在您的应用程序的 DefaultController 中创建一个注销路由。

    /**
     * @Route("/logout", name="logout")
     */
    public function logoutAction() {
        if (($this->getParameter('cas_logout_target') !== null) && (!empty($this->getParameter('cas_logout_target')))) {
            \phpCAS::client(CAS_VERSION_2_0, $this->getParameter('host'), $this->getParameter('port'), is_null($this->getParameter('path')) ? '' : $this->getParameter('path'), true);
            \phpCAS::logoutWithRedirectService($this->getParameter('cas_logout_target'));
        } else {
            \phpCAS::client(CAS_VERSION_2_0, $this->getParameter('host'), $this->getParameter('port'), is_null($this->getParameter('path')) ? '' : $this->getParameter('path'), true);
            \phpCAS::logout();
        }
    }

注销处理器

在某些应用程序(如 EasyAdminBundle)中,您可能需要使用注销成功处理器,以便 EasyAdmin 使用此注销成功处理器来调用 /logout。

  • 创建 src/Handler/AuthenticationHandler.php 并添加以下代码:
<?php

namespace App\Handler;

use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;

class AuthenticationHandler implements LogoutSuccessHandlerInterface
{
    protected $cas_logout_target;
    
    public function __construct($cas_logout_target)
    {
        $this->cas_logout_target = $cas_logout_target;        
    }
    
    public function onLogoutSuccess(Request $request) : Response
    {
        if(!empty($this->cas_logout_target)) {
            \phpCAS::logoutWithRedirectService($this->cas_logout_target);
        } else {
            \phpCAS::logout();
        }
    }
}
  • 在 config/services.yaml 中,在 "services:" 下添加以下行:
     authentication_handler:
         class: App\Handler\AuthenticationHandler
         arguments: ['%cas_logout_target%']
         public: false
  • 在 config/packages/security.yaml 中,添加以下行(对于 cas: true 的防火墙):
             logout:
                 path: /logout
                 success_handler: authentication_handler
                 invalidate_session: false

附加属性

Jasig Cas 服务器可以在 phpCAS::getAttributes() 函数中返回除主要属性(通常为 uid)之外的附加属性。

您可以使用以下代码在控制器中获取附加属性:

...
$attributes = $this->get('security.token_storage')->getToken()->getAttributes();
...

注解

路由注解只有在安装此包后才会运行。

composer require doctrine/annotations