如何将自定义值传递给 Azure AD B2C 并需要 return 该参数以及响应或通用重定向 URI?
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?
我必须处理多个登录 pages/applications 需要重定向到一个公共登录页面 index.html 并且需要访问自定义字符串来识别请求应用。令牌生成端点对所有登录页面都是通用的。
场景:
我有多个登录页面
1: Login1.html
2: Login2.html
两个登录页面的令牌生成端点将相同。
从 Azure AD B2C 应用程序成功进行身份验证后,它将重定向到一个公共登录页面 'http://localhost:6420'。 (这是我在 azure ad b2c 应用程序门户中设置为重定向 URL 的值)。
我需要传递一个自定义字符串,我需要为其识别用户当前从哪个 UI 登录。即如果用户从 UI 登录,则进行二次验证=66=] 页面,然后我需要从 login1.html 传递 'log1' 并需要在我的公共登录页面中访问此值。
我已经尝试使用 'state' 和 'extraQueryParameters',但不确定它们如何按照我的要求工作。
const loginRequest = {
scopes: ["openid", "profile"],
extraQueryParameters: { campaignId: 'hawaii', ui_locales: 'es' }
};
如有任何帮助,我们将不胜感激。提前致谢。
-- 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();
}
}
state
是你应该使用的。
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;
};
我必须处理多个登录 pages/applications 需要重定向到一个公共登录页面 index.html 并且需要访问自定义字符串来识别请求应用。令牌生成端点对所有登录页面都是通用的。
场景:
我有多个登录页面
1: Login1.html
2: Login2.html
两个登录页面的令牌生成端点将相同。
从 Azure AD B2C 应用程序成功进行身份验证后,它将重定向到一个公共登录页面 'http://localhost:6420'。 (这是我在 azure ad b2c 应用程序门户中设置为重定向 URL 的值)。
我需要传递一个自定义字符串,我需要为其识别用户当前从哪个 UI 登录。即如果用户从 UI 登录,则进行二次验证=66=] 页面,然后我需要从 login1.html 传递 'log1' 并需要在我的公共登录页面中访问此值。
我已经尝试使用 'state' 和 'extraQueryParameters',但不确定它们如何按照我的要求工作。
const loginRequest = {
scopes: ["openid", "profile"],
extraQueryParameters: { campaignId: 'hawaii', ui_locales: 'es' }
};
如有任何帮助,我们将不胜感激。提前致谢。
-- 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();
}
}
state
是你应该使用的。
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;
};