How can I pass a custom value to Azure AD B2C and need to return that parameter along with the response or with the common Redirect URI?

纵饮孤独 提交于 2020-07-10 07:35:41

问题


I have to handle multiple login pages/applications which need to redirect to a common landing page index.html and need to access custom string to identify the requested application. The token generation endpoint is common for all login pages.

Scenario :

  • I have multiple login pages

    1: Login1.html

    2: Login2.html

    Token generation endpoint will be same for both logins page.

  • After successful authentication from Azure AD B2C application it will redirect to a common landing page 'http://localhost:6420'. (This is the value I have set as redirect URL in the azure ad b2c application portal).

  • I need to pass a custom string for which I need to identify from which UI the user is currently logged in. i.e for a secondary validation if a user logged in from the login1.html page, then I need to pass 'log1' from the login1.html and need to access this value in my common landing page.

I have tried with both 'state' and also with 'extraQueryParameters' but not sure how these works as my requirement.

const loginRequest = {
        scopes: ["openid", "profile"],
        extraQueryParameters: { campaignId: 'hawaii', ui_locales: 'es' }
      };

Any help would be highly appreciated. Thanks in advance.

-- app-config.ts

    import { Configuration } from 'msal';
    import { MsalAngularConfiguration } from '@azure/msal-angular';
    
    // this checks if the app is running on IE
    export const isIE = window.navigator.userAgent.indexOf('MSIE ') > -1 || window.navigator.userAgent.indexOf('Trident/') > -1;
    
    export const b2cPolicies = {
        names: {
            signUpSignIn: "b2c_1_susi",
            resetPassword: "b2c_1_reset",
        },
        authorities: {
            signUpSignIn: {
                authority: "https://fabrikamb2c.b2clogin.com/fabrikamb2c.onmicrosoft.com/b2c_1_susi"
            },
            resetPassword: {
                authority: "https://fabrikamb2c.b2clogin.com/fabrikamb2c.onmicrosoft.com/b2c_1_reset"
            } 
        }
    }
    
    export const apiConfig: {b2cScopes: string[], webApi: string} = {
        b2cScopes: ['https://fabrikamb2c.onmicrosoft.com/helloapi/demo.read'],
        webApi: 'https://fabrikamb2chello.azurewebsites.net/hello'
    };
    
    export const msalConfig: Configuration = {
        auth: {
            clientId: "e760cab2-b9a1-4c0d-86fb-ff7084abd902",
            authority: b2cPolicies.authorities.signUpSignIn.authority,
            redirectUri: "http://localhost:6420/",
            postLogoutRedirectUri: "http://localhost:6420/",
            navigateToLoginRequestUrl: true,
            validateAuthority: false,
          },
        cache: {
            cacheLocation: "localStorage",
            storeAuthStateInCookie: isIE, // Set this to "true" to save cache in cookies to address trusted zones limitations in IE
        },
    }
    
    export const loginRequest = {
        scopes: ['openid', 'profile'],
 extraQueryParameters: { userPage: 'Page1', ui_locales: 'es' }
    };
    
    // Scopes you enter will be used for the access token request for your web API
    export const tokenRequest: {scopes: string[]} = {
        scopes: apiConfig.b2cScopes // i.e. [https://fabrikamb2c.onmicrosoft.com/helloapi/demo.read]
    };
    
    export const protectedResourceMap: [string, string[]][] = [
        [apiConfig.webApi, apiConfig.b2cScopes] // i.e. [https://fabrikamb2chello.azurewebsites.net/hello, ['https://fabrikamb2c.onmicrosoft.com/helloapi/demo.read']]
    ];
    
    export const msalAngularConfig: MsalAngularConfiguration = {
        popUp: !isIE,
        consentScopes: [
            ...loginRequest.scopes,
            ...tokenRequest.scopes,
 

   ],
    unprotectedResources: [], // API calls to these coordinates will NOT activate MSALGuard
    protectedResourceMap,     // API calls to these coordinates will activate MSALGuard
    extraQueryParameters: { campaignId: 'hawaii', ui_locales: 'es' } 
}

-- app.component.ts

import { Component, OnInit } from '@angular/core';
import { BroadcastService, MsalService} from '@azure/msal-angular';
import { Logger, CryptoUtils } from 'msal';
import { isIE, b2cPolicies } from './app-config';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent implements OnInit {
  title = 'Azure AD B2C';
  isIframe = false;
  loggedIn = false;

  constructor(private broadcastService: BroadcastService, private authService: MsalService) { }
  
  ngOnInit() {

    this.isIframe = window !== window.parent && !window.opener;
    this.checkAccount();

    // event listeners for authentication status
    this.broadcastService.subscribe('msal:loginSuccess', (success) => {

    // We need to reject id tokens that were not issued with the default sign-in policy.
    // "acr" claim in the token tells us what policy is used (NOTE: for new policies (v2.0), use "tfp" instead of "acr")
    // To learn more about b2c tokens, visit https://docs.microsoft.com/en-us/azure/active-directory-b2c/tokens-overview
      if (success.idToken.claims['acr'] !== b2cPolicies.names.signUpSignIn) {
        window.alert("Password has been reset successfully. \nPlease sign-in with your new password");
        return this.authService.logout()
      }

      console.log('login succeeded. id token acquired at: ' + new Date().toString());
      console.log(success);

      this.checkAccount();
    });

    this.broadcastService.subscribe('msal:loginFailure', (error) => {
      console.log('login failed');
      console.log(error);

        // Check for forgot password error
        // Learn more about AAD error codes at https://docs.microsoft.com/en-us/azure/active-directory/develop/reference-aadsts-error-codes
        if (error.errorMessage.indexOf('AADB2C90118') > -1) {
          if (isIE) {
            this.authService.loginRedirect(b2cPolicies.authorities.resetPassword);
          } else {
            this.authService.loginPopup(b2cPolicies.authorities.resetPassword);
          }
        }
    });

    // redirect callback for redirect flow (IE)
    this.authService.handleRedirectCallback((authError, response) => {
      if (authError) {
        console.error('Redirect Error: ', authError.errorMessage);
        return;
      }

      console.log('Redirect Success: ', response);
    });

    this.authService.setLogger(new Logger((logLevel, message, piiEnabled) => {
      console.log('MSAL Logging: ', message);
    }, {
      correlationId: CryptoUtils.createNewGuid(),
      piiLoggingEnabled: false
    }));
  }

  // other methods
  checkAccount() {
    this.loggedIn = !!this.authService.getAccount();
  }

  login() {
    if (isIE) {
      this.authService.loginRedirect();
    } else {
      this.authService.loginPopup();
    }
  }

  logout() {
    this.authService.logout();
  }
}

回答1:


state is what you should use.

https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-js-pass-custom-state-authentication-request

The state parameter, as defined by OAuth 2.0, is included in an authentication request and is also returned in the token response to prevent cross-site request forgery attacks. By default, Microsoft Authentication Library for JavaScript (MSAL.js) passes a randomly generated unique state parameter value in the authentication requests.

The state parameter can also be used to encode information of the app's state before redirect. You can pass the user's state in the app, such as the page or view they were on, as input to this parameter. The MSAL.js library allows you to pass your custom state as state parameter in the Request object

The passed in state is appended to the unique GUID set by MSAL.js when sending the request. When the response is returned, MSAL.js checks for a state match and then returns the custom passed in state in the Response object as accountState.

let loginRequest = {
    scopes: ["user.read", "user.write"],
    state: "page_url"
}

myMSALObj.loginPopup(loginRequest);

// ...


export type AuthResponse = {
    uniqueId: string;
    tenantId: string;
    tokenType: string;
    idToken: IdToken;
    accessToken: string;
    scopes: Array<string>;
    expiresOn: Date;
    account: Account;
    accountState: string;
};


来源:https://stackoverflow.com/questions/62500094/how-can-i-pass-a-custom-value-to-azure-ad-b2c-and-need-to-return-that-parameter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!