Parola değişikliği veya güncelleştirilmiş Koşullu Erişim ilkeleri gibi nedenlerle Microsoft Entra Id'ye yönelik sessiz belirteç istekleri başarısız olabilir. Daha sık hatalar yenileme belirtecinin 24 saatlik ömrünün dolmasından ve tarayıcının üçüncü taraf tanımlama bilgilerini engellemesi nedeniyle gerçekleşir ve bu da kullanıcının kimliğini doğrulamaya devam etmek için gizli iframe'lerin kullanılmasını engeller. Bu durumlarda, belirteçleri almak için etkileşimli yöntemlerden birini (kullanıcıdan isteyebilir) çağırmanız gerekir:
Açılır pencere veya yeniden yönlendirme deneyimi arasındaki seçim, uygulama akışınıza bağlıdır:
Erişim belirtecinin erişim belirteci isteğini oluştururken eklenmesini istediğiniz API kapsamlarını ayarlayabilirsiniz. Erişim belirtecinde istenen tüm kapsamlar verilemiyor olabilir. Bu, kullanıcının onayına bağlıdır.
Aşağıdaki kod, daha önce açıklanan deseni açılır bir deneyim için yöntemlerle birleştirir:
// MSAL.js v2 exposes several account APIs, logic to determine which account to use is the responsibility of the developer
const account = publicClientApplication.getAllAccounts()[0];
const accessTokenRequest = {
scopes: ["user.read"],
account: account,
};
publicClientApplication
.acquireTokenSilent(accessTokenRequest)
.then(function (accessTokenResponse) {
// Acquire token silent success
let accessToken = accessTokenResponse.accessToken;
// Call your API with token
callApi(accessToken);
})
.catch(function (error) {
//Acquire token silent failure, and send an interactive request
if (error instanceof InteractionRequiredAuthError) {
publicClientApplication
.acquireTokenPopup(accessTokenRequest)
.then(function (accessTokenResponse) {
// Acquire token interactive success
let accessToken = accessTokenResponse.accessToken;
// Call your API with token
callApi(accessToken);
})
.catch(function (error) {
// Acquire token interactive failure
console.log(error);
});
}
console.log(error);
});
Aşağıdaki kod, daha önce açıklanan deseni açılır bir deneyim için yöntemlerle birleştirir:
const accessTokenRequest = {
scopes: ["user.read"],
};
userAgentApplication
.acquireTokenSilent(accessTokenRequest)
.then(function (accessTokenResponse) {
// Acquire token silent success
// Call API with token
let accessToken = accessTokenResponse.accessToken;
})
.catch(function (error) {
//Acquire token silent failure, and send an interactive request
if (error.errorMessage.indexOf("interaction_required") !== -1) {
userAgentApplication
.acquireTokenPopup(accessTokenRequest)
.then(function (accessTokenResponse) {
// Acquire token interactive success
})
.catch(function (error) {
// Acquire token interactive failure
console.log(error);
});
}
console.log(error);
});
MSAL Angular sarmalayıcı, erişim belirteçlerini otomatik olarak sessizce alan ve API'lere HTTP isteklerine ekleyen HTTP kesme noktası oluşturucuyu sağlar.
YAPıLANDıRMA seçeneğinde API'lerin protectedResourceMap
kapsamlarını belirtebilirsiniz. MsalInterceptor
belirteçleri otomatik olarak alırken belirtilen kapsamları istemektedir.
// In app.module.ts
import { PublicClientApplication, InteractionType } from "@azure/msal-browser";
import { MsalInterceptor, MsalModule } from "@azure/msal-angular";
@NgModule({
declarations: [
// ...
],
imports: [
// ...
MsalModule.forRoot(
new PublicClientApplication({
auth: {
clientId: "Enter_the_Application_Id_Here",
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: isIE,
},
}),
{
interactionType: InteractionType.Popup,
authRequest: {
scopes: ["user.read"],
},
},
{
interactionType: InteractionType.Popup,
protectedResourceMap: new Map([
["https://graph.microsoft.com/v1.0/me", ["user.read"]],
]),
}
),
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: MsalInterceptor,
multi: true,
},
],
bootstrap: [AppComponent],
})
export class AppModule {}
Sessiz belirteç alımının başarılı ve başarısız olması için MSAL Angular abone olabileceğiniz olaylar sağlar. Aboneliği kaldırmayı unutmamak da önemlidir.
import { MsalBroadcastService } from '@azure/msal-angular';
import { EventMessage, EventType } from '@azure/msal-browser';
import { filter, Subject, takeUntil } from 'rxjs';
// In app.component.ts
export class AppComponent implements OnInit {
private readonly _destroying$ = new Subject<void>();
constructor(private broadcastService: MsalBroadcastService) { }
ngOnInit() {
this.broadcastService.msalSubject$
.pipe(
filter((msg: EventMessage) => msg.eventType === EventType.ACQUIRE_TOKEN_SUCCESS),
takeUntil(this._destroying$)
)
.subscribe((result: EventMessage) => {
// Do something with event payload here
});
}
ngOnDestroy(): void {
this._destroying$.next(undefined);
this._destroying$.complete();
}
}
Alternatif olarak, çekirdek MSAL.js kitaplığında açıklandığı gibi alma belirteci yöntemlerini kullanarak belirteçleri açıkça alabilirsiniz.
MSAL Angular sarmalayıcı, erişim belirteçlerini otomatik olarak sessizce alan ve API'lere HTTP isteklerine ekleyen HTTP kesme noktası oluşturucuyu sağlar.
YAPıLANDıRMA seçeneğinde API'lerin protectedResourceMap
kapsamlarını belirtebilirsiniz. MsalInterceptor
belirteçleri otomatik olarak alırken belirtilen kapsamları istemektedir.
// app.module.ts
@NgModule({
declarations: [
// ...
],
imports: [
// ...
MsalModule.forRoot(
{
auth: {
clientId: "Enter_the_Application_Id_Here",
},
},
{
popUp: !isIE,
consentScopes: ["user.read", "openid", "profile"],
protectedResourceMap: [
["https://graph.microsoft.com/v1.0/me", ["user.read"]],
],
}
),
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: MsalInterceptor,
multi: true,
},
],
bootstrap: [AppComponent],
})
export class AppModule {}
Sessiz belirteç alımının başarılı ve başarısız olması için MSAL Angular abone olabileceğiniz geri çağırmalar sağlar. Aboneliği kaldırmayı unutmamak da önemlidir.
// In app.component.ts
ngOnInit() {
this.subscription = this.broadcastService.subscribe("msal:acquireTokenFailure", (payload) => {
});
}
ngOnDestroy() {
this.broadcastService.getMSALSubject().next(1);
if (this.subscription) {
this.subscription.unsubscribe();
}
}
Alternatif olarak, çekirdek MSAL.js kitaplığında açıklandığı gibi alma belirteci yöntemlerini kullanarak belirteçleri açıkça alabilirsiniz.
Aşağıdaki kod, daha önce açıklanan deseni açılır bir deneyim için yöntemlerle birleştirir:
import {
InteractionRequiredAuthError,
InteractionStatus,
} from "@azure/msal-browser";
import { AuthenticatedTemplate, useMsal } from "@azure/msal-react";
function ProtectedComponent() {
const { instance, inProgress, accounts } = useMsal();
const [apiData, setApiData] = useState(null);
useEffect(() => {
if (!apiData && inProgress === InteractionStatus.None) {
const accessTokenRequest = {
scopes: ["user.read"],
account: accounts[0],
};
instance
.acquireTokenSilent(accessTokenRequest)
.then((accessTokenResponse) => {
// Acquire token silent success
let accessToken = accessTokenResponse.accessToken;
// Call your API with token
callApi(accessToken).then((response) => {
setApiData(response);
});
})
.catch((error) => {
if (error instanceof InteractionRequiredAuthError) {
instance
.acquireTokenPopup(accessTokenRequest)
.then(function (accessTokenResponse) {
// Acquire token interactive success
let accessToken = accessTokenResponse.accessToken;
// Call your API with token
callApi(accessToken).then((response) => {
setApiData(response);
});
})
.catch(function (error) {
// Acquire token interactive failure
console.log(error);
});
}
console.log(error);
});
}
}, [instance, accounts, inProgress, apiData]);
return <p>Return your protected content here: {apiData}</p>;
}
function App() {
return (
<AuthenticatedTemplate>
<ProtectedComponent />
</AuthenticatedTemplate>
);
}
Alternatif olarak, React bileşeninin dışında bir belirteç almanız gerekiyorsa çağırabilirsiniz acquireTokenSilent
ancak başarısız olursa etkileşime geri dönmemeniz gerekir. Tüm etkileşimler bileşen ağacınızdaki bileşenin MsalProvider
altında gerçekleşmelidir.
// MSAL.js v2 exposes several account APIs, logic to determine which account to use is the responsibility of the developer
const account = publicClientApplication.getAllAccounts()[0];
const accessTokenRequest = {
scopes: ["user.read"],
account: account,
};
// Use the same publicClientApplication instance provided to MsalProvider
publicClientApplication
.acquireTokenSilent(accessTokenRequest)
.then(function (accessTokenResponse) {
// Acquire token silent success
let accessToken = accessTokenResponse.accessToken;
// Call your API with token
callApi(accessToken);
})
.catch(function (error) {
//Acquire token silent failure
console.log(error);
});
Aşağıdaki desen daha önce açıklandığı gibi ancak belirteçleri etkileşimli olarak almak için bir yeniden yönlendirme yöntemiyle gösterilmiştir. Sayfa yüklemesinde aramanız ve beklemeniz handleRedirectPromise
gerekir.
const redirectResponse = await publicClientApplication.handleRedirectPromise();
if (redirectResponse !== null) {
// Acquire token silent success
let accessToken = redirectResponse.accessToken;
// Call your API with token
callApi(accessToken);
} else {
// MSAL.js v2 exposes several account APIs, logic to determine which account to use is the responsibility of the developer
const account = publicClientApplication.getAllAccounts()[0];
const accessTokenRequest = {
scopes: ["user.read"],
account: account,
};
publicClientApplication
.acquireTokenSilent(accessTokenRequest)
.then(function (accessTokenResponse) {
// Acquire token silent success
// Call API with token
let accessToken = accessTokenResponse.accessToken;
// Call your API with token
callApi(accessToken);
})
.catch(function (error) {
//Acquire token silent failure, and send an interactive request
console.log(error);
if (error instanceof InteractionRequiredAuthError) {
publicClientApplication.acquireTokenRedirect(accessTokenRequest);
}
});
}
Aşağıdaki desen daha önce açıklandığı gibi ancak belirteçleri etkileşimli olarak almak için bir yeniden yönlendirme yöntemiyle gösterilmiştir. Yeniden yönlendirme geri çağırmasını daha önce belirtildiği gibi kaydetmeniz gerekir.
function authCallback(error, response) {
// Handle redirect response
}
userAgentApplication.handleRedirectCallback(authCallback);
const accessTokenRequest: AuthenticationParameters = {
scopes: ["user.read"],
};
userAgentApplication
.acquireTokenSilent(accessTokenRequest)
.then(function (accessTokenResponse) {
// Acquire token silent success
// Call API with token
let accessToken = accessTokenResponse.accessToken;
})
.catch(function (error) {
//Acquire token silent failure, and send an interactive request
console.log(error);
if (error.errorMessage.indexOf("interaction_required") !== -1) {
userAgentApplication.acquireTokenRedirect(accessTokenRequest);
}
});
İsteğe bağlı talepler isteme
İsteğe bağlı talepleri aşağıdaki amaçlarla kullanabilirsiniz:
- Uygulamanız için belirteçlere ek talepler ekleyin.
- Microsoft Entra ID'nin belirteçlerde döndürdüğü belirli taleplerin davranışını değiştirin.
- Uygulamanız için özel beyanlar ekleyebilir ve bunlara erişebilirsiniz.
içinde IdToken
isteğe bağlı talepler istemek için, sınıfın claimsRequest
alanına AuthenticationParameters.ts
dizeli bir talep nesnesi gönderebilirsiniz.
var claims = {
optionalClaims: {
idToken: [
{
name: "auth_time",
essential: true,
},
],
},
};
var request = {
scopes: ["user.read"],
claimsRequest: JSON.stringify(claims),
};
myMSALObj.acquireTokenPopup(request);
Daha fazla bilgi edinmek için bkz . İsteğe bağlı talepler.
Bu kod daha önce açıklanan kodla aynıdır, ancak yeniden yönlendirmeleri işlemek için önyükleme yapmanızı MsalRedirectComponent
öneririz. MsalInterceptor
yapılandırmaları yeniden yönlendirmeleri kullanacak şekilde de değiştirilebilir.
// In app.module.ts
import { PublicClientApplication, InteractionType } from "@azure/msal-browser";
import {
MsalInterceptor,
MsalModule,
MsalRedirectComponent,
} from "@azure/msal-angular";
@NgModule({
declarations: [
// ...
],
imports: [
// ...
MsalModule.forRoot(
new PublicClientApplication({
auth: {
clientId: "Enter_the_Application_Id_Here",
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: isIE,
},
}),
{
interactionType: InteractionType.Redirect,
authRequest: {
scopes: ["user.read"],
},
},
{
interactionType: InteractionType.Redirect,
protectedResourceMap: new Map([
["https://graph.microsoft.com/v1.0/me", ["user.read"]],
]),
}
),
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: MsalInterceptor,
multi: true,
},
],
bootstrap: [AppComponent, MsalRedirectComponent],
})
export class AppModule {}
Bu kod, daha önce açıklanan kodla aynıdır.
Başarısız olursa acquireTokenSilent
, öğesine acquireTokenRedirect
geri dönme. Bu yöntem bir tam çerçeve yeniden yönlendirmesi başlatır ve uygulamaya geri dönerken yanıt işlenir. Bu bileşen yeniden yönlendirmeden döndükten sonra işlendiğinde, acquireTokenSilent
belirteçler önbellekten çekileceği için artık başarılı olmalıdır.
import {
InteractionRequiredAuthError,
InteractionStatus,
} from "@azure/msal-browser";
import { AuthenticatedTemplate, useMsal } from "@azure/msal-react";
function ProtectedComponent() {
const { instance, inProgress, accounts } = useMsal();
const [apiData, setApiData] = useState(null);
useEffect(() => {
const accessTokenRequest = {
scopes: ["user.read"],
account: accounts[0],
};
if (!apiData && inProgress === InteractionStatus.None) {
instance
.acquireTokenSilent(accessTokenRequest)
.then((accessTokenResponse) => {
// Acquire token silent success
let accessToken = accessTokenResponse.accessToken;
// Call your API with token
callApi(accessToken).then((response) => {
setApiData(response);
});
})
.catch((error) => {
if (error instanceof InteractionRequiredAuthError) {
instance.acquireTokenRedirect(accessTokenRequest);
}
console.log(error);
});
}
}, [instance, accounts, inProgress, apiData]);
return <p>Return your protected content here: {apiData}</p>;
}
function App() {
return (
<AuthenticatedTemplate>
<ProtectedComponent />
</AuthenticatedTemplate>
);
}
Alternatif olarak, React bileşeninin dışında bir belirteç almanız gerekiyorsa çağırabilirsiniz acquireTokenSilent
ancak başarısız olursa etkileşime geri dönmemeniz gerekir. Tüm etkileşimler bileşen ağacınızdaki bileşenin MsalProvider
altında gerçekleşmelidir.
// MSAL.js v2 exposes several account APIs, logic to determine which account to use is the responsibility of the developer
const account = publicClientApplication.getAllAccounts()[0];
const accessTokenRequest = {
scopes: ["user.read"],
account: account,
};
// Use the same publicClientApplication instance provided to MsalProvider
publicClientApplication
.acquireTokenSilent(accessTokenRequest)
.then(function (accessTokenResponse) {
// Acquire token silent success
let accessToken = accessTokenResponse.accessToken;
// Call your API with token
callApi(accessToken);
})
.catch(function (error) {
//Acquire token silent failure
console.log(error);
});