Risk ve ilke gerçek zamanlı olarak değerlendirildiğinden, bazı kaynak API'lerinin belirteç ömrü 28 saate kadar artabilir. Bu uzun ömürlü belirteçler, Microsoft Kimlik Doğrulama Kitaplığı (MSAL) tarafından proaktif olarak yenilenerek uygulamalarınızın dayanıklılığını artırır.
CAE'yi kullanmak için hem uygulamanızın hem de eriştiği kaynak API'sinin CAE etkin olması gerekir. Bir kaynak API'si CAE uygularsa ve uygulamanız CAE'yi işleyebileceğini bildirirse, uygulamanız bu kaynak için CAE belirteçleri alır. Bu nedenle, uygulamanızı CAE'ye hazır olarak bildirirseniz, uygulamanızın Microsoft Identity erişim belirteçlerini kabul eden tüm kaynak API'leri için CAE talep sınamasını işlemesi gerekir.
Ancak kodunuzu CAE özellikli kaynakları destekleyecek şekilde hazırlamak, CAE'yi desteklemeyen API'lerle çalışma becerisini sınırlamaz. Uygulamanız CAE yanıtlarını doğru şekilde işlemezse, teknik olarak geçerli olan ancak CAE nedeniyle iptal edilen bir belirteç kullanarak bir API çağrısını tekrar tekrar deneyebilir.
CAE nedeniyle çağrıyı reddeden kaynak API'sinden gelen yanıtları işlemek için kod ekleyerek başlayın. CAE ile, erişim belirteci iptal edildiğinde veya API kullanılan IP adresinde bir değişiklik algıladığında API'ler 401 durumunu ve WWW-Authenticate üst bilgisini döndürür. Üst bilgi, WWW-Authenticate uygulamanın yeni bir erişim belirteci almak için kullanabileceği bir Talep Sınaması içerir.
Bu koşullar karşılandığında uygulama, MSAL.NETayıklayabilir ve kodunu çözebilir.
if (APIresponse.IsSuccessStatusCode)
{
// ...
}
else
{
if (APIresponse.StatusCode == System.Net.HttpStatusCode.Unauthorized
&& APIresponse.Headers.WwwAuthenticate.Any())
{
string claimChallenge = WwwAuthenticateParameters.GetClaimChallengeFromResponseHeaders(APIresponse.Headers);
Uygulamanız daha sonra talep sınamasını kullanarak kaynak için yeni bir erişim belirteci alır.
try
{
authResult = await _clientApp.AcquireTokenSilent(scopes, firstAccount)
.WithClaims(claimChallenge)
.ExecuteAsync()
.ConfigureAwait(false);
}
catch (MsalUiRequiredException)
{
try
{
authResult = await _clientApp.AcquireTokenInteractive(scopes)
.WithClaims(claimChallenge)
.WithAccount(firstAccount)
.ExecuteAsync()
.ConfigureAwait(false);
}
// ...
Uygulamanız CAE özellikli bir kaynak tarafından döndürülen talep sınamasını işlemeye hazır olduğunda, Microsoft Identity'e uygulamanızın CAE'ye hazır olduğunu söyleyebilirsiniz. Bunu MSAL uygulamanızda yapmak için İstemci Özelliklerini "cp1"kullanarak Genel İstemcinizi oluşturun.
_clientApp = PublicClientApplicationBuilder.Create(App.ClientId)
.WithDefaultRedirectUri()
.WithAuthority(authority)
.WithClientCapabilities(new [] {"cp1"})
.Build();
Bu koşullar karşılandığında uygulama, talep sınamasını API yanıt üst bilgisinden aşağıdaki gibi ayıklayabilir:
try {
const response = await fetch(apiEndpoint, options);
if (response.status === 401 && response.headers.get('www-authenticate')) {
const authenticateHeader = response.headers.get('www-authenticate');
const claimsChallenge = parseChallenges(authenticateHeader).claims;
// use the claims challenge to acquire a new access token...
}
} catch(error) {
// ...
}
// helper function to parse the www-authenticate header
function parseChallenges(header) {
const schemeSeparator = header.indexOf(' ');
const challenges = header.substring(schemeSeparator + 1).split(',');
const challengeMap = {};
challenges.forEach((challenge) => {
const [key, value] = challenge.split('=');
challengeMap[key.trim()] = window.decodeURI(value.replace(/['"]+/g, ''));
});
return challengeMap;
}
Uygulamanız daha sonra talep sınamasını kullanarak kaynak için yeni bir erişim belirteci alır.
const tokenRequest = {
claims: window.atob(claimsChallenge), // decode the base64 string
scopes: ['User.Read'],
account: msalInstance.getActiveAccount()
};
let tokenResponse;
try {
tokenResponse = await msalInstance.acquireTokenSilent(tokenRequest);
} catch (error) {
if (error instanceof InteractionRequiredAuthError) {
tokenResponse = await msalInstance.acquireTokenPopup(tokenRequest);
}
}
Uygulamanız CAE özellikli bir kaynak tarafından döndürülen talep sınamasını işlemeye hazır olduğunda, MSAL yapılandırmasına bir clientCapabilities özellik ekleyerek Microsoft Identity'e uygulamanızın CAE'ye hazır olduğunu bildirebilirsiniz.
const msalConfig = {
auth: {
clientId: 'Enter_the_Application_Id_Here',
clientCapabilities: ["CP1"]
// remaining settings...
}
}
const msalInstance = new PublicClientApplication(msalConfig);
Bu koşullar karşılandığında uygulama, talep sınamasını API yanıt üst bilgisinden aşağıdaki gibi ayıklayabilir:
import msal # pip install msal
import requests # pip install requests
import www_authenticate # pip install www-authenticate==0.9.2
# Once your application is ready to handle the claim challenge returned by a CAE-enabled resource, you can tell Microsoft Identity your app is CAE-ready. To do this in your MSAL application, build your Public Client using the Client Capabilities of "cp1".
app = msal.PublicClientApplication("your_client_id", client_capabilities=["cp1"])
...
# When these conditions are met, the app can extract the claims challenge from the API response header as follows:
response = requests.get("<your_resource_uri_here>")
if response.status_code == 401 and response.headers.get('WWW-Authenticate'):
parsed = www_authenticate.parse(response.headers['WWW-Authenticate'])
claims = parsed.get("bearer", {}).get("claims")
# Your app would then use the claims challenge to acquire a new access token for the resource.
if claims:
auth_result = app.acquire_token_interactive(["scope"], claims_challenge=claims)
CP1 İstemci Özelliği için destek bildirme
Uygulama yapılandırmanızda, uygulamanızın istemci özelliğini ekleyerek CAE'yi desteklediğini CP1 bildirmeniz gerekir. Bu, JSON özelliği kullanılarak client_capabilities belirtilir.
{
"client_id" : "<your_client_id>",
"authorization_user_agent" : "DEFAULT",
"redirect_uri" : "msauth://<pkg>/<cert_hash>",
"multiple_clouds_supported":true,
"broker_redirect_uri_registered": true,
"account_mode": "MULTIPLE",
"client_capabilities": "CP1",
"authorities" : [
{
"type": "AAD",
"audience": {
"type": "AzureADandPersonalMicrosoftAccount"
}
}
]
}
Çalışma Zamanında CAE Zorluklarına Yanıt Verme
Yanıt bir talep sınaması içeriyorsa bir kaynağa istekte bulunup ayıklayın ve sonraki istekte kullanmak üzere MSAL'ye geri aktarın.
final HttpURLConnection connection = ...;
final int responseCode = connection.getResponseCode();
// Check the response code...
if (200 == responseCode) {
// ...
} else if (401 == responseCode) {
final String authHeader = connection.getHeaderField("WWW-Authenticate");
if (null != authHeader) {
final ClaimsRequest claimsRequest = WWWAuthenticateHeader
.getClaimsRequestFromWWWAuthenticateHeaderValue(authHeader);
// Feed the challenge back into MSAL, first silently, then interactively if required
final AcquireTokenSilentParameters silentParameters = new AcquireTokenSilentParameters.Builder()
.fromAuthority(authority)
.forAccount(account)
.withScopes(scope)
.withClaims(claimsRequest)
.build();
try {
final IAuthenticationResult silentRequestResult = mPublicClientApplication.acquireTokenSilent(silentParameters);
// If successful - your business logic goes here...
} catch (final Exception e) {
if (e instanceof MsalUiRequiredException) {
// Retry the request interactively, passing in any claims challenge...
}
}
}
} else {
// ...
}
// Don't forget to close your connection
Aşağıdaki kod parçacıkları sessizce belirteç alma, kaynak sağlayıcısına http çağrısı yapma ve ardından CAE servis talebi işleme akışını açıklar. Sessiz çağrı taleplerle başarısız olduysa ek bir etkileşim çağrısı gerekebilir.
CP1 istemci özelliği için destek bildirme
Uygulama yapılandırmanızda, uygulamanızın istemci özelliğini ekleyerek CAE'yi desteklediğini CP1 bildirmeniz gerekir. Bu, özelliği kullanılarak clientCapabilities belirtilir.
let clientConfigurations = MSALPublicClientApplicationConfig(clientId: "contoso-app-ABCDE-12345",
redirectUri: "msauth.com.contoso.appbundle://auth",
authority: try MSALAuthority(url: URL(string: "https://login.microsoftonline.com/organizations")!))
clientConfigurations.clientApplicationCapabilities = ["CP1"]
let applicationContext = try MSALPublicClientApplication(configuration: clientConfigurations)
Talep zorluklarını ayrıştırma için bir yardımcı işlevi uygulayın.
func parsewwwAuthenticateHeader(headers:Dictionary<AnyHashable, Any>) -> String? {
// !! This is a sample code and is not validated, please provide your own implementation or fully test the sample code provided here.
// Can also refer here for our internal implementation: https://github.com/AzureAD/microsoft-authentication-library-common-for-objc/blob/dev/IdentityCore/src/webview/embeddedWebview/challangeHandlers/MSIDPKeyAuthHandler.m#L112
guard let wwwAuthenticateHeader = headers["WWW-Authenticate"] as? String else {
// did not find the header, handle gracefully
return nil
}
var parameters = [String: String]()
// regex mapping
let regex = try! NSRegularExpression(pattern: #"(\w+)="([^"]*)""#)
let matches = regex.matches(in: wwwAuthenticateHeader, range: NSRange(wwwAuthenticateHeader.startIndex..., in: wwwAuthenticateHeader))
for match in matches {
if let keyRange = Range(match.range(at: 1), in: wwwAuthenticateHeader),
let valueRange = Range(match.range(at: 2), in: wwwAuthenticateHeader) {
let key = String(wwwAuthenticateHeader[keyRange])
let value = String(wwwAuthenticateHeader[valueRange])
parameters[key] = value
}
}
guard let jsonData = try? JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) else {
// cannot convert params into json date, end gracefully
return nil
}
return String(data: jsonData, encoding: .utf8)
}
401 / talep sınamalarını yakalayın ve ayrıştırma.
let response = .... // HTTPURLResponse object from 401'd service response
switch response.statusCode {
case 200:
// ...succeeded!
break
case 401:
let headers = response.allHeaderFields
// Parse header fields
guard let wwwAuthenticateHeaderString = self.parsewwwAuthenticateHeader(headers: headers) else {
// 3.7 no valid wwwAuthenticateHeaderString is returned from header, end gracefully
return
}
let claimsRequest = MSALClaimsRequest(jsonString: wwwAuthenticateHeaderString, error: nil)
// Create claims request
let parameters = MSALSilentTokenParameters(scopes: "Enter_the_Protected_API_Scopes_Here", account: account)
parameters.claimsRequest = claimsRequest
// Acquire token silently again with the claims challenge
applicationContext.acquireTokenSilent(with: parameters) { (result, error) in
if let error = error {
// error happened end flow gracefully, and handle error. (e.g. interaction required)
return
}
guard let result = result else {
// no result end flow gracefully
return
}
// Success - You got a token!
}
break
default:
break
}
Bu koşullar karşılandığında uygulama, talep sınamasını API yanıt üst bilgisinden aşağıdaki gibi ayıklayabilir:
İstemci özelliklerini tanıtma.
client, err := New("client-id", WithAuthority(authority), WithClientCapabilities([]string{"cp1"}))
üst bilgisini ayrıştırın WWW-Authenticate ve sonuçta elde edilen sınamayı MSAL-Go'ya geçirin.
// No snippet provided at this time
Talep sınamasıyla sessizce belirteç almayı deneme.
var ar AuthResult;
ar, err := client.AcquireTokenSilent(ctx, tokenScope, public.WithClaims(claims))
Bir kullanıcıda oturum açıp azure portalını kullanarak kullanıcının oturumunu iptal ederek uygulamanızı test edebilirsiniz. Uygulama CAE özellikli API'yi bir sonraki çağırışında kullanıcıdan yeniden kimlik doğrulaması istenir.