认证JavaScript API参考

Fabric 扩展性工具包提供了一个 JavaScript API,用于获取认证令牌,可用于访问 Fabric API、Azure 服务以及任何受 Entra 保护的应用程序。 本文提供了全面的API参考和使用示例。

小窍门

快速入门指南请参见 “获取 Microsoft Entra 代币”。

API 参考

acquireFrontendAccessToken(params: AcquireFrontendAccessTokenParams): Promise<AccessToken>;

export interface AcquireFrontendAccessTokenParams {
    scopes: string[];
}

export interface AccessToken {
    token: string;
}

注释

当前的扩展性工具包实现支持带作用域的基本令牌获取。 高级功能如完全同意提示和条件访问处理尚未可用,但未来发布可能会添加。

该 API 返回一个 AccessToken 包含:

  • 令牌:用于授权头部的JWT令牌字符串

基本用法

简单代币获取

// Acquire a token with default Fabric permissions
const token = await workloadClient.auth.acquireFrontendAccessToken({ scopes: [] });

// Use the token in API calls
const response = await fetch('https://api.fabric.microsoft.com/v1/workspaces', {
  headers: {
    'Authorization': `Bearer ${token.token}`,
    'Content-Type': 'application/json'
  }
});

具有特定范围的代币

// Request specific scopes for Azure Storage
const token = await workloadClient.auth.acquireFrontendAccessToken({
  scopes: ['https://storage.azure.com/user_impersonation']
});

代币使用示例

Fabric API 访问

该令牌可以直接与 Fabric REST API 一起使用:

async function listWorkspaces() {
  const token = await workloadClient.auth.acquireFrontendAccessToken({ scopes: [] });
  
  const response = await fetch('https://api.fabric.microsoft.com/v1/workspaces', {
    headers: {
      'Authorization': `Bearer ${token.token}`
    }
  });
  
  return await response.json();
}

Azure service access

使用作用域指定您需要访问的 Azure 服务:

async function readFromStorage(accountName, containerName, blobName) {
  const token = await workloadClient.auth.acquireFrontendAccessToken({
    scopes: ['https://storage.azure.com/user_impersonation']
  });
  
  const url = `https://${accountName}.blob.core.windows.net/${containerName}/${blobName}`;
  const response = await fetch(url, {
    headers: {
      'Authorization': `Bearer ${token.token}`,
      'x-ms-version': '2021-12-02'
    }
  });
  
  return await response.text();
}

自定义应用访问

访问您自己的Entra安全应用:

async function callCustomAPI() {
  const token = await workloadClient.auth.acquireFrontendAccessToken({
    scopes: ['https://myapp.contoso.com/data.read']
  });
  
  const response = await fetch('https://myapp.contoso.com/api/data', {
    headers: {
      'Authorization': `Bearer ${token.token}`
    }
  });
  
  return await response.json();
}

参数参考

scopes

一组范围字符串,用来指定你的令牌所需的权限。

常见的Azure服务范围:

  • https://storage.azure.com/user_impersonation - Azure 存储
  • https://vault.azure.net/user_impersonation - Azure Key Vault
  • https://management.azure.com/user_impersonation - Azure 资源管理器
  • https://graph.microsoft.com/User.Read - Microsoft 图

用法示例:

const token = await workloadClient.auth.acquireFrontendAccessToken({
  scopes: [
    'https://storage.azure.com/user_impersonation'
  ]
});

空作用域数组: 使用空数组获取带有默认 Fabric 权限的令牌:

const token = await workloadClient.auth.acquireFrontendAccessToken({ scopes: [] });

可扩展性工具包自动处理同意工作流程:

  • 初始请求:如果缺少同意,弹窗会弹出
  • 用户交互:用户授予或拒绝权限
  • 自动关闭:用户作后弹窗自动关闭
  • 令牌交付:如果成功,令牌会返回给你的应用程序

该工具包会自动管理同意弹窗,但你可以自定义重定向URI的行为。 创建一个重定向页面来处理同意回复:

// redirect.js - Handle consent redirect
const redirectUriPath = '/close';
const url = new URL(window.location.href);

if (url.pathname?.startsWith(redirectUriPath)) {
  // Handle consent errors
  if (url?.hash?.includes("error")) {
    // Extract error information
    const errorMatch = url.hash.match(/error=([^&]+)/);
    const errorDescription = url.hash.match(/error_description=([^&]+)/);
    
    // Handle specific errors
    if (url.hash.includes("AADSTS650052")) {
      console.error("Service principal not configured");
    } else if (url.hash.includes("AADSTS65004")) {
      console.error("User declined consent");
    }
  }
  
  // Always close the popup immediately
  window.close();
}

跨租户访问资源:

// Request consent for cross-tenant access
const token = await workloadClient.auth.acquireAccessToken({
  additionalScopesToConsent: ['https://api.partner-app.com/data.read']
});

错误处理

常见错误情境

async function robustTokenAcquisition() {
  try {
    return await workloadClient.auth.acquireAccessToken();
  } catch (error) {
    switch (error.code) {
      case 'user_cancelled':
        console.log('User cancelled the consent dialog');
        break;
      case 'consent_required':
        console.log('Additional consent required');
        break;
      case 'interaction_required':
        console.log('User interaction required');
        break;
      default:
        console.error('Authentication error:', error.message);
    }
    throw error;
  }
}

令牌过期处理

class TokenManager {
  private currentToken: AccessToken | null = null;
  
  async getValidToken(): Promise<AccessToken> {
    if (!this.currentToken || this.isTokenExpired(this.currentToken)) {
      this.currentToken = await workloadClient.auth.acquireAccessToken();
    }
    return this.currentToken;
  }
  
  private isTokenExpired(token: AccessToken): boolean {
    // Add buffer time to prevent requests with almost-expired tokens
    const bufferMinutes = 5;
    const expirationWithBuffer = new Date(token.expiresOn.getTime() - (bufferMinutes * 60 * 1000));
    return new Date() >= expirationWithBuffer;
  }
}

最佳做法

令牌缓存与重用

  • 缓存令牌:将令牌存储在内存中直到过期
  • 自动刷新:在过期前实现自动令牌刷新
  • 安全存储:绝不要将令牌持久化到本地存储或Cookie

范围管理

  • 最小范围:只请求你需要的权限
  • 渐进同意:随着功能使用请求额外范围
  • 作用域验证:验证令牌在 API 调用前包含必要的范围

高级错误处理

  • 优雅降级:在认证失败时提供备用功能
  • 用户消息:明确说明为什么需要权限
  • 试逻辑:为瞬态故障实现适当的重试机制

性能优化

  • 并行请求:尽可能并行获取多个服务的令牌
  • 批处理作:组 API 调用以最小化令牌获取开销
  • 缓存管理:实施高效的令牌缓存策略