You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitHub Enterprise Pages认证咨询:非账号密码替代方案

问题描述

我们公司在用GitHub Enterprise,我把仓库里的静态内容发布到了Pages站点,浏览器登录后能正常访问,但桌面C#应用调用接口时返回错误页面——因为站点需要认证。我不想硬编码账号密码,也不想强制用户手动输入凭证,想找其他替代认证方案(比如应用ID/密钥、证书等),同时要知道仓库怎么配置,以及应用里怎么注入认证信息。

使用场景:
这是公司内部应用(源码就在该仓库),我计划用GitHub Pages做版本检测:发布新版本时更新Pages上的内容,应用启动时获取并解析这些内容,发现有新版本就通知用户。

附当前使用的C#代码:

using System.Net.Http;
using Newtonsoft.Json;

private const string Scheme = "https";
private const string BaseDomain = @"mycompany.domain";
private const string BasePath = @"pages/myorg/myrepo";
private const string InfoPath = "info.json";

var uriString = $"{Scheme}://{BaseDomain}/{BasePath}/";
var httpClient = new HttpClient{BaseAddress = new Uri(uriString)};

var infoString = httpClient.GetStringAsync(InfoPath).Result;

var info = JsonConvert.DeserializeObject<Info>(infoString);

可行解决方案

方案1:使用GitHub Enterprise个人访问令牌(PAT)

仓库/账号配置

  1. 生成PAT:在GitHub Enterprise个人设置里,进入「Developer settings」→「Personal access tokens」,生成令牌时勾选repo和pages:read权限(至少要能读取Pages内容,可按需调整)。
  2. 令牌存储:因为是内部应用,可将PAT作为应用的内置配置,但绝对不能直接写在源码里,建议用加密配置文件、环境变量或者应用内置的安全存储来保存。

C#应用实现

在HttpClient请求中添加Bearer认证头即可:

using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;

private const string Scheme = "https";
private const string BaseDomain = @"mycompany.domain";
private const string BasePath = @"pages/myorg/myrepo";
private const string InfoPath = "info.json";
// 从加密配置或环境变量读取,禁止硬编码
private const string GitHubPat = "your-generated-pat";

var uriString = $"{Scheme}://{BaseDomain}/{BasePath}/";
var httpClient = new HttpClient{BaseAddress = new Uri(uriString)};
// 添加认证头
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", GitHubPat);

// 建议用await替代.Result,避免阻塞线程
var infoString = await httpClient.GetStringAsync(InfoPath);
var info = JsonConvert.DeserializeObject<Info>(infoString);

方案2:使用GitHub Enterprise应用程序(GitHub App)

适合需要更规范权限管理、令牌可回收的场景,比PAT更安全可控。

仓库/组织配置

  1. 创建GitHub App:在GitHub Enterprise的组织设置里,进入「GitHub Apps」→「New GitHub App」,设置应用名称、主页URL,权限部分勾选「Pages」读取权限和「Repository contents」读取权限。
  2. 生成私钥:创建应用后,在应用设置页生成并下载PEM格式的私钥文件。
  3. 安装应用:将创建好的GitHub App安装到目标仓库所在的组织,确保应用能访问目标仓库。
  4. 获取安装ID:在应用的「Installations」页面找到对应组织的安装记录,复制安装ID。

C#应用实现

需要先生成JWT令牌获取安装访问令牌,再用该令牌请求Pages内容:

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
using Newtonsoft.Json;
using Jose;

// GitHub App配置信息
private const string AppId = "your-github-app-id";
private const string PrivateKeyPath = "path-to-your-private-key.pem";
private const string InstallationId = "your-installation-id";
private const string Scheme = "https";
private const string BaseDomain = @"mycompany.domain";
private const string BasePath = @"pages/myorg/myrepo";
private const string InfoPath = "info.json";

// 生成JWT令牌用于认证GitHub App
private static string GenerateJwtToken()
{
    var privateKey = File.ReadAllText(PrivateKeyPath);
    var rsa = RSA.Create();
    rsa.ImportFromPem(privateKey.ToCharArray());
    
    var payload = new Dictionary<string, object>
    {
        {"iat", DateTimeOffset.UtcNow.ToUnixTimeSeconds()},
        {"exp", DateTimeOffset.UtcNow.AddMinutes(10).ToUnixTimeSeconds()},
        {"iss", AppId}
    };
    
    return JWT.Encode(payload, rsa, JwsAlgorithm.RS256);
}

// 获取安装访问令牌
private static async Task<string> GetInstallationToken()
{
    var jwtToken = GenerateJwtToken();
    using var httpClient = new HttpClient();
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwtToken);
    
    var response = await httpClient.PostAsync($"https://{BaseDomain}/api/v3/app/installations/{InstallationId}/access_tokens", null);
    response.EnsureSuccessStatusCode();
    
    var tokenResponse = await response.Content.ReadFromJsonAsync<Dictionary<string, string>>();
    return tokenResponse["token"];
}

// 主逻辑
var installationToken = await GetInstallationToken();
var uriString = $"{Scheme}://{BaseDomain}/{BasePath}/";
using var httpClient = new HttpClient{BaseAddress = new Uri(uriString)};
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", installationToken);

var infoString = await httpClient.GetStringAsync(InfoPath);
var info = JsonConvert.DeserializeObject<Info>(infoString);

注意:需要安装Jose-jwt和System.Text.Json NuGet包来处理JWT和JSON解析。

方案3:客户端证书认证(需GitHub Enterprise服务器支持)

如果公司已有统一的客户端证书体系,可采用这种方式,需要管理员配合配置服务器。

仓库/服务器配置

  1. 确认公司的GitHub Enterprise已启用客户端证书认证(需管理员操作)。
  2. 生成客户端证书(比如用OpenSSL生成),将证书公钥上传到GitHub Enterprise的个人或组织设置中,关联到有权访问Pages的账号。

C#应用实现

在HttpClient中加载客户端证书即可:

using System.Net.Http;
using System.Security.Cryptography.X509Certificates;
using Newtonsoft.Json;

private const string Scheme = "https";
private const string BaseDomain = @"mycompany.domain";
private const string BasePath = @"pages/myorg/myrepo";
private const string InfoPath = "info.json";
private const string ClientCertPath = "path-to-client-cert.pfx";
private const string ClientCertPassword = "cert-password"; // 证书有密码时填写

var uriString = $"{Scheme}://{BaseDomain}/{BasePath}/";
var handler = new HttpClientHandler();
// 加载客户端证书
var cert = new X509Certificate2(ClientCertPath, ClientCertPassword);
handler.ClientCertificates.Add(cert);

var httpClient = new HttpClient(handler){BaseAddress = new Uri(uriString)};

var infoString = await httpClient.GetStringAsync(InfoPath);
var info = JsonConvert.DeserializeObject<Info>(infoString);

方案选择建议
  • 快速实现选个人访问令牌(PAT):配置简单,代码改动小,适合小型内部应用。
  • 长期维护选GitHub App:权限更精细,令牌可回收、自动过期,适合需要规范管理的应用。
  • 已有证书体系选客户端证书:贴合公司现有安全架构,无需额外管理令牌。

内容的提问来源于stack exchange,提问作者C Robinson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 21:14:57