Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
476 views
in Technique[技术] by (71.8m points)

php - Azure Active Directory SSO with Laravel

I'm doing sso with azure active directory. I have done the setup on azure and go the keys. I'm using metrogistics/laravel-azure-ad-oauth (https://packagist.org/packages/metrogistics/laravel-azure-ad-oauth) package on laravel to do this. However, when I hit the url http://localhost:8000/login/microsoft , I got redirected to microsoft login page and given an error message.

enter image description here

I have added following configurations to env file and did whatever package has demanded.

AZURE_AD_CLIENT_ID=XXXXXXXXXXXXXXXXXX (this is application id from azure) AZURE_AD_CLIENT_SECRET=XXXXXXXXX (created a new key on azure)

It's been two days I'm searching the internet but could not find a solution. What is it I'm missing here?

Thanks,

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

For those people who are still struggling to Azure Active Directory SSO in Laravel. And if you are willing to use SAML. Here is the repo they can use.

https://github.com/aacotroneo/laravel-saml2

It's very simple to use provided you have done SSO setup correctly on Azure portal.

It is two step process

Step 1- Setup SSO project on Azure Portal


a) Go to Azure Active Directory and then Enterprise Application

b) Add New Application and choose Non-gallery Application

c) Click Set up single sign on and then click on SAML Box

d) Edit the basic SAML configuration and add the following

Identifier (Entity ID) - https://my-laravel-website.com/saml2/aad/metadata

Reply URL (Assertion Consumer Service URL) - https://my-laravel-website.com/saml2/aad/acs

(From where these urls are coming, I will explain in Step 2. For now just save it.)

e) Download Federation Metadata XML from SAML Signing Certificate section, on your system

f) Next assign users to your current SAML SSO project.

Note- If there is no user exist in your account. Then you need to create one and assign some role(it's necessary).

This is the tutorial to setup step 1 https://www.youtube.com/watch?v=xn_8Fm7S7y8

.

Step 2- Install and configure Laravel SAML 2 package in your Project


a) run composer require aacotroneo/laravel-saml2

b) run php artisan vendor:publish --provider="AacotroneoSaml2Saml2ServiceProvider"

c) config/saml2_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 (AacotroneoSaml2HttpControllersSaml2Controller).
     * 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' => 'AppHttpControllersAuthSAML2LoginController',
);

Note - Part d) of Step 1 is coming from the following

enter image description here

d) Create a new file config/saml2/aad_idp_settings.php and copy the contents of config/saml2/test_idp_settings.php into it. Change $this_idp_env_id in aad_idp_settings.php to 'AAD'. So the final aad_idp_settings.php will look like the following.

<?php

// If you choose to use ENV vars to define these values, give this IdP its own env var names
// so you can define different values for each IdP, all starting with 'SAML2_'.$this_idp_env_id
$this_idp_env_id = 'AAD';

//This is variable is for simplesaml example only.
// For real IdP, you must set the url values in the 'idp' config to conform to the IdP's real urls.
$idp_host = env('SAML2_'.$this_idp_env_id.'_IDP_HOST', 'http://localhost:8000/simplesaml');

return $settings = array(

    /*****
     * One Login Settings
     */

    // If 'strict' is True, then the PHP Toolkit will reject unsigned
    // or unencrypted messages if it expects them signed or encrypted
    // Also will reject the messages if not strictly follow the SAML
    // standard: Destination, NameId, Conditions ... are validated too.
    'strict' => true, //@todo: make this depend on laravel config

    // Enable debug mode (to print errors)
    'debug' => env('APP_DEBUG', false),

    // Service Provider Data that we are deploying
    'sp' => array(

        // Specifies constraints on the name identifier to be used to
        // represent the requested subject.
        // Take a look on lib/Saml2/Constants.php to see the NameIdFormat supported
        'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',

        // Usually x509cert and privateKey of the SP are provided by files placed at
        // the certs folder. But we can also provide them with the following parameters
        'x509cert' => env('SAML2_'.$this_idp_env_id.'_SP_x509',''),
        'privateKey' => env('SAML2_'.$this_idp_env_id.'_SP_PRIVATEKEY',''),

        // Identifier (URI) of the SP entity.
        // Leave blank to use the '{idpName}_metadata' route, e.g. 'test_metadata'.
        'entityId' => env('SAML2_'.$this_idp_env_id.'_SP_ENTITYID',''),

        // Specifies info about where and how the <AuthnResponse> message MUST be
        // returned to the requester, in this case our SP.
        'assertionConsumerService' => array(
            // URL Location where the <Response> from the IdP will be returned,
            // using HTTP-POST binding.
            // Leave blank to use the '{idpName}_acs' route, e.g. 'test_acs'
            'url' => '',
        ),
        // Specifies info about where and how the <Logout Response> message MUST be
        // returned to the requester, in this case our SP.
        // Remove this part to not include any URL Location in the metadata.
        'singleLogoutService' => array(
            // URL Location where the <Response> from the IdP will be returned,
            // using HTTP-Redirect binding.
            // Leave blank to use the '{idpName}_sls' route, e.g. 'test_sls'
            'url' => '',
        ),
    ),

    // Identity Provider Data that we want connect with our SP
    'idp' => array(
        // Identifier of the IdP entity  (must be a URI)
        'entityId' => env('SAML2_'.$this_idp_env_id.'_IDP_ENTITYID', $idp_host . '/saml2/idp/metadata.php'),
        // SSO endpoint info of the IdP. (Authentication Request protocol)
        'singleSignOnService' => array(
            // URL Target of the IdP where the SP will send the Authentication Request Message,
            // using HTTP-Redirect binding.
            'url' => env('SAML2_'.$this_idp_env_id.'_IDP_SSO_URL', $idp_host . '/saml2/idp/SSOService.php'),
        ),
        // SLO endpoint info of the IdP.
        'singleLogoutService' => array(
            // URL Location of the IdP where the SP will send the SLO Request,
            // using HTTP-Redirect binding.
            'url' => env('SAML2_'.$this_idp_env_id.'_IDP_SL_URL', $idp_host . '/saml2/idp/SingleLogoutService.php'),
        ),
        // Public x509 certificate of the IdP
        'x509cert' => env('SAML2_'.$this_idp_env_id.'_IDP_x509', 'MIID/TCCAuWgAwIBAgIJAI4R3WyjjmB1MA0GCS'),
        /*
         *  Instead of use the whole x509cert you can use a fingerprint
         *  (openssl x509 -noout -fingerprint -in "idp.crt" to generate it)
         */
        // 'certFingerprint' => '',
    ),



    /***
     *
     *  OneLogin advanced settings
     *
     *
     */
    // Security settings
    'security' => array(

        /** signatures and encryptions offered */

        // Indicates that the nameID of the <samlp:logoutRequest> sent by this SP
        // will be encrypted.
        'nameIdEncrypted' => false,

        // Indicates whether the <samlp:AuthnRequest> messages sent by this SP
        // will be signed.              [The Metadata of the SP will offer this info]
        'authnRequestsSigned' => false,

        // Indicates whether the <samlp:logoutRequest> messages sent by this SP
        // will be signed.
        'logoutRequestSigned' => false,

        // Indicates whether the <samlp:logoutResponse> messages sent by this SP
        // will be signed.
        'logoutResponseSigned' => false,

        /* Sign the Metadata
         False || True (use sp certs) || array (
                                                    keyFileName => 'metadata.key',
                                                    certFileName => 'metadata.crt'
                                                )
        */
        'signMetadata' => false,


        /** signatures and encryptions required **/

        // Indicates a requirement for the <samlp:Response>, <samlp:LogoutRequest> and
        // <samlp:LogoutResponse> elements received by this SP to be signed.
        'wantMessagesSigned' => false,

        // Indicates a requirement for the <saml:Assertion> elements received by
        // this SP to be signed.        [The Metadata of the SP will offer this info]
        'wantAssertionsSigned' => false,

        // Indicates a requirement for the NameID received by
        // this SP to be encrypted.
        'wantNameIdEncrypted' => false,

        // Authentication context.
        // Set to false and no AuthContext will be sent in

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...