typescript - Použití MSAL Angular pro přístup k chráněné Azure Function
Tato otázka je založena na ukázkovém kódu poskytnutém společností Microsoft:
https://learn.microsoft.com/en-us/samples/azure-samples/active-directory-javascript-singlepageapp-angular/active-directory-javascript-singlepageapp-angular/
Soubor app.module.ts byl nakonfigurován a aplikace se může úspěšně přihlásit prostřednictvím přihlašovací obrazovky Azure B2C.
Existuje také funkce Azure, která jednoduše vrací JSON objekt s jednou řetězcovou vlastností „text“ prostřednictvím HTTP GET požadavku. Funkce byla nakonfigurována tak, aby používala autentizaci přes Azure B2C. Toto bylo potvrzeno návštěvou URL funkce v prohlížeči, přihlášením přes přihlašovací obrazovku B2C a návratem JSON objektu z funkce.
Komponenta, která volá chráněné API, vypadá takto:
import { Component, OnInit } from '@angular/core';
import { MsalService } from '@azure/msal-angular';
import { HttpClient } from '@angular/common/http';
const FUNCTION_ENDPOINT = 'function-url-here';
export interface MyInterface {
text: string;
}
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
value: MyInterface;
constructor(private authService: MsalService, private http: HttpClient) { }
ngOnInit() {
this.getValue();
}
getValue() {
this.http.get<MyInterface>(FUNCTION_ENDPOINT).toPromise()
.then(value => {
this.value = value;
});
}
}
Když je funkce ověřování vypnuta, JSON z funkce je vrácen do aplikace Angular. Když je funkce ověřování zapnuta, následující chyba je vypsána do konzole prohlížeče:
Přístup k XMLHttpRequest na 'https://mytenant.b2clogin.com/mytenant.onmicrosoft.com/oauth2/v2.0/authorize?response_type=id_token&redirect_uri=https%3A%2F%functionname.azurewebsites.net%2F.auth%2Flogin%2Faad%2Fcallback&client_id=SAMPLE-STRING&scope=openid+profile+email&response_mode=form_post&p=b2c_1_signupsignin1&nonce=SAMPLE-STRING&state=redir%3D%252Fapi%252FHttpTrigger2%253Fcode%SAMPLE-STRING' (přesměrováno z 'https://functionname.azurewebsites.net/api/HttpTrigger2?code=SAMPLE-STRING') z původu 'null' bylo zablokováno politikou CORS: Na požadovaném zdroji není přítomen žádný záhlaví 'Access-Control-Allow-Origin'.
Druhá chyba:
core.js:4002 CHYBA Error: Nepožádané (v promise): HttpErrorResponse: {"headers":{"normalizedNames":{},"lazyUpdate":null,"headers":{}},"status":0,"statusText":"Neznámá chyba","url":"https://functionname.azurewebsites.net/api/HttpTrigger2?code=SAMPLE-STRING","ok":false,"name":"HttpErrorResponse","message":"Chybová odpověď HTTP pro https://functionname.azurewebsites.net/api/HttpTrigger2?code=SAMPLE-STRING: 0 Neznámá chyba","error":{"isTrusted":true}}
Ve konzoli je také varování:
Cross-Origin Read Blocking (CORB) zablokoval odpověď z jiného původu https://mytenant.b2clogin.com/mytenant.onmicrosoft.com/oauth2/v2.0/authorize?response_type=id_token&redirect_uri=https%3A%2F%2Ffunctionname.azurewebsites.net%2F.auth%2Flogin%2Faad%2Fcallback&client_id=SAMPLE-STRING&scope=openid+profile+email&response_mode=form_post&p=b2c_1_signupsignin1&nonce=SAMPLE-STRING&state=redir%3D%252Fapi%252FHttpTrigger2%253Fcode%SAMPLE-STRING s MIME typem text/html. Více informací naleznete na https://www.chromestatus.com/feature/5629709824032768.
URL pro aplikaci Angular je http://localhost:4200/. Zde je konfigurace CORS pro Azure Function:
Co lze udělat, aby Angular aplikace mohla provádět autentizované požadavky na Azure Function?
Odpověď č. 1
AAD a AAD B2C nepodporují CORS, jak je uvedeno v dokumentaci MSDN. To znamená, že když vaše Angular aplikace volá Function API bez tokenu a tím je přesměrována na bod AAD B2C pro ověření, máte neřešitelný problém. Trik s takzvaným „implicitním tokem“ spočívá v tom, že tomu zabráníte tím, že si nejprve zajistíte token vydaný při přímém volání z Angular aplikace na B2C endpoint. A protože registrace aplikace, kam je tento token přiřazen, má oprávnění k přístupu k Function API, token může být implicitně vygenerován a předán do Function API, které jej pak přijme. A pak nedochází k žádnému přesměrování a tím pádem také k žádným problémům s CORS.
Často - alespoň podle mých zkušeností - je problém CORS, na který narazíte, poněkud zavádějící, protože zakrývá skutečný problém, kterým může být 1) uživatel není vůbec autentizován (token úplně chybí) nebo 2) token pro volání API není implicitně generován a vložen do HTTP volání. Navrhuji následující kontroly:
MsalModulesprávně nakonfigurován (poznámka:MsalModule.forRoot(<config>)nepodporuje dynamické konfigurace)- Uživatelský token je k dispozici v SessionStorage nebo LocalStorage bez chyb
Implicitní tok je správně nakonfigurován s:
MsalInterceptorzaregistrován jako poskytovatel
protectedResourceMapje nakonfigurován pro URL funkce
Nedávno jsem vytvořil a zdokumentoval referenční řešení s Angular & Azure Function spojené s AAD B2C. Zdroj a soubor readme najdete zde: https://github.com/garaio/DevCamp-AzureServerless/tree/master/Solutions/D04-AAD-B2C-multi-tenancy#client-app-deployment.
Odpověď č. 2
Přístupový token můžete získat odkazem na tento dokument. Nezapomeňte aktualizovat protectedResourceMap na vaši hodnotu. Pro B2C by to mělo být něco jako
protectedResourceMap: {"https://tonyb2ctest.onmicrosoft.com/test", ["user_impersonation"]}
Pak můžete zavolat funkci API s přístupovým tokenem.


