Php Azure Active Directory SSO与Laravel

Php Azure Active Directory SSO与Laravel,php,laravel,azure,active-directory,single-sign-on,Php,Laravel,Azure,Active Directory,Single Sign On,我正在用azure active directory执行sso。我已经在azure上完成了设置,并按了键。我在laravel上使用metrogistics/laravel azure ad oauth()包来实现这一点。然而,当我点击url时,我被重定向到microsoft登录页面,并收到一条错误消息 我已经将以下配置添加到env文件中,并按照包的要求进行了操作 AZURE\u AD\u客户端\u ID=xxxxxxxxxxxxxxxxxxxx(这是来自AZURE的应用程序ID) AZURE_

我正在用azure active directory执行sso。我已经在azure上完成了设置,并按了键。我在laravel上使用metrogistics/laravel azure ad oauth()包来实现这一点。然而,当我点击url时,我被重定向到microsoft登录页面,并收到一条错误消息

我已经将以下配置添加到env文件中,并按照包的要求进行了操作

AZURE\u AD\u客户端\u ID=xxxxxxxxxxxxxxxxxxxx(这是来自AZURE的应用程序ID) AZURE_AD_CLIENT_SECRET=XXXXXXXXX(在AZURE上创建了一个新密钥)

我在网上搜索已经两天了,但找不到解决办法。我错过了什么


感谢,

对于那些仍在
Azure Active Directory
SSO
Laravel
中苦苦挣扎的人们。如果你愿意使用SAML。 这是他们可以使用的回购协议

只要您在Azure portal上正确地完成了SSO设置,使用起来非常简单

这是一个分两步的过程

步骤1-在Azure门户上设置SSO项目
a)进入
Azure Active Directory
,然后进入
Enterprise Application

b)添加新应用程序并选择
非图库应用程序

c)单击
设置单一登录
,然后单击
SAML

d)编辑
基本SAML配置
并添加以下内容

标识符(实体ID)-

回复URL(断言消费者服务URL)-

(这些URL来自何处,我将在步骤2中解释。现在只需保存它。)

e)从系统上的
SAML签名证书
部分下载
联盟元数据XML

f)下一步将用户分配到当前的SAML SSO项目

注意-如果您的帐户中不存在用户。然后您需要创建一个并分配一些角色(这是必要的)。

这是设置步骤1的教程

步骤2-在项目中安装和配置Laravel SAML 2软件包
a)run
composer需要aacotroneo/laravel-saml2

b)run
php工匠供应商:publish--provider=“Aacotroneo\Saml2\Saml2ServiceProvider”

c)config/saml2\u settings.php

<?php

return $settings = array(

    /**
     * Array of IDP prefixes to be configured e.g. 'idpNames' => ['test1', 'test2', 'test3'],
     * Separate routes will be automatically registered for each IDP specified with IDP name as prefix
     * Separate config file saml2/<idpName>_idp_settings.php should be added & configured accordingly
     */
    'idpNames' => ['aad'],

    /**
     * If 'useRoutes' is set to true, the package defines five new routes for reach entry in idpNames:
     *
     *    Method | URI                                | Name
     *    -------|------------------------------------|------------------
     *    POST   | {routesPrefix}/{idpName}/acs       | saml_acs
     *    GET    | {routesPrefix}/{idpName}/login     | saml_login
     *    GET    | {routesPrefix}/{idpName}/logout    | saml_logout
     *    GET    | {routesPrefix}/{idpName}/metadata  | saml_metadata
     *    GET    | {routesPrefix}/{idpName}/sls       | saml_sls
     */
    'useRoutes' => true,

    /**
     * Optional, leave empty if you want the defined routes to be top level, i.e. "/{idpName}/*"
     */
    'routesPrefix' => 'saml2',

    /**
     * which middleware group to use for the saml routes
     * Laravel 5.2 will need a group which includes StartSession
     */
    'routesMiddleware' => ['saml'],

    /**
     * Indicates how the parameters will be
     * retrieved from the sls request for signature validation
     */
    'retrieveParametersFromServer' => false,

    /**
     * Where to redirect after logout
     */
    'logoutRoute' => '/login',

    /**
     * Where to redirect after login if no other option was provided
     */
    'loginRoute' => '/dashboard',

    /**
     * Where to redirect after login if no other option was provided
     */
    'errorRoute' => '/login',

    // If 'proxyVars' is True, then the Saml lib will trust proxy headers
    // e.g X-Forwarded-Proto / HTTP_X_FORWARDED_PROTO. This is useful if
    // your application is running behind a load balancer which terminates
    // SSL.
    'proxyVars' => true,

    /**
     * (Optional) Which class implements the route functions.
     * If commented out, defaults to this lib's controller (Aacotroneo\Saml2\Http\Controllers\Saml2Controller).
     * If you need to extend Saml2Controller (e.g. to override the `login()` function to pass
     * a `$returnTo` argument), this value allows you to pass your own controller, and have
     * it used in the routes definition.
     */
     'saml2_controller' => 'App\Http\Controllers\Auth\SAML2LoginController',
);
e)现在我们需要放置以下环境变量

SAML2_AAD_IDP_ENTITYID=
SAML2_AAD_IDP_SSO_URL=
SAML2_AAD_IDP_SL_URL=
SAML2_AAD_IDP_x509=
前3个环境变量的值将从此处开始

最后一个环境变量将来自以下内容

f)运行
php artisan make:provider SAML2ServiceProvider
。这将在
app/Providers/SAML2ServiceProvider.php
中创建一个文件

boot方法中粘贴以下代码段

Event::listen('Aacotroneo\Saml2\Events\Saml2LoginEvent', function (Saml2LoginEvent $event) {
            $messageId = $event->getSaml2Auth()->getLastMessageId();
            // Add your own code preventing reuse of a $messageId to stop replay attacks

            $user = $event->getSaml2User();
            $userData = [
                'id' => $user->getUserId(),
                'attributes' => $user->getAttributes(),
                'assertion' => $user->getRawSamlAssertion()
            ];

            $inputs = [
                'sso_user_id'  => $user->getUserId(),
                'username'     => self::getValue($user->getAttribute('http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name')),
                'email'        => self::getValue($user->getAttribute('http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name')),
                'first_name'   => self::getValue($user->getAttribute('http://schemas.microsoft.com/identity/claims/displayname')),
                'last_name'    => self::getValue($user->getAttribute('http://schemas.microsoft.com/identity/claims/displayname')),
                'password'     => Hash::make('anything'),
             ];

            $user = User::where('sso_user_id', $inputs['sso_user_id'])->where('email', $inputs['email'])->first();
            if(!$user){
                $res = PortalUser::store($inputs);
                if($res['status'] == 'success'){
                    $user  = $res['data'];
                    Auth::guard('web')->login($user);
                }else{
                    Log::info('SAML USER Error '.$res['messages']);
                }
            }else{
                Auth::guard('web')->login($user);
            }

        });
最后在
config/app.php
providers数组中注册此提供程序

测试SAML和SSO

您是否尝试登录或立即弹出此对话框?你在哪里注册的应用程序?Azure门户(portal.Azure.com)中的Azure广告刀片?当我尝试登录时(在提供凭据后)会弹出此窗口。是的,我在Azure portalIs的Azure AD blade中注册了应用程序您的应用程序是多租户应用程序吗?我看到你已经将权限设置为“公共”权限,允许任何AAD租户的用户登录。我的实际应用程序是多租户。但我创建了一个示例应用程序来测试最简单的流。如果这样做有效,我将转向多租户。您是否错过了步骤1的e?如果我希望能够连接到多个Azure租户,如何实现这一点?
Event::listen('Aacotroneo\Saml2\Events\Saml2LoginEvent', function (Saml2LoginEvent $event) {
            $messageId = $event->getSaml2Auth()->getLastMessageId();
            // Add your own code preventing reuse of a $messageId to stop replay attacks

            $user = $event->getSaml2User();
            $userData = [
                'id' => $user->getUserId(),
                'attributes' => $user->getAttributes(),
                'assertion' => $user->getRawSamlAssertion()
            ];

            $inputs = [
                'sso_user_id'  => $user->getUserId(),
                'username'     => self::getValue($user->getAttribute('http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name')),
                'email'        => self::getValue($user->getAttribute('http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name')),
                'first_name'   => self::getValue($user->getAttribute('http://schemas.microsoft.com/identity/claims/displayname')),
                'last_name'    => self::getValue($user->getAttribute('http://schemas.microsoft.com/identity/claims/displayname')),
                'password'     => Hash::make('anything'),
             ];

            $user = User::where('sso_user_id', $inputs['sso_user_id'])->where('email', $inputs['email'])->first();
            if(!$user){
                $res = PortalUser::store($inputs);
                if($res['status'] == 'success'){
                    $user  = $res['data'];
                    Auth::guard('web')->login($user);
                }else{
                    Log::info('SAML USER Error '.$res['messages']);
                }
            }else{
                Auth::guard('web')->login($user);
            }

        });