节点在线、应用在线、配置在线使用令牌查询
大石头 authored at 2021-12-16 19:49:30
3.43 KiB
Stardust
using System;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using NewLife;
using NewLife.Remoting;
using NewLife.Remoting.Models;
using NewLife.Security;
using Stardust.Data;
using Stardust.Server;
using Xunit;

namespace ServerTest.Controllers;

/// <summary>网关配置接口鉴权安全测试(安全V-10)。验证 /Gateway/* 需应用身份,防公网拓扑泄露</summary>
public class GatewaySecurityTests
{
    private readonly TestServer _server;

    public GatewaySecurityTests()
    {
#pragma warning disable CS0618, ASPDEPR008
        _server = new TestServer(WebHost.CreateDefaultBuilder()
            .UseStartup<Startup>());
#pragma warning restore CS0618, ASPDEPR008
    }

    private async Task<HttpResponseMessage> GetConfigAsync(String query)
    {
        var client = _server.CreateClient();
        return await client.GetAsync($"/Gateway/config?{query}");
    }

    private App CreateApp(String name, String secret)
    {
        var app = new App { Name = name, Enable = true };
        if (!secret.IsNullOrEmpty()) app.Secret = secret;
        app.Insert();
        return app;
    }

    [Fact(DisplayName = "无凭据访问网关配置被401拒绝")]
    public async Task NoCredential_Rejected()
    {
        var resp = await GetConfigAsync("");

        Assert.Equal(401, (Int32)resp.StatusCode);
    }

    [Fact(DisplayName = "错误密钥访问被401拒绝")]
    public async Task WrongSecret_Rejected()
    {
        var app = CreateApp("gw_" + Rand.NextString(8), "gw-secret");
        try
        {
            var resp = await GetConfigAsync($"appId={app.Name}&secret=wrong");

            Assert.Equal(401, (Int32)resp.StatusCode);
        }
        finally
        {
            app.Delete();
        }
    }

    [Fact(DisplayName = "空密钥应用无法通过凭据校验")]
    public async Task EmptySecretApp_Rejected()
    {
        var app = CreateApp("gw_" + Rand.NextString(8), "");
        try
        {
            var resp = await GetConfigAsync($"appId={app.Name}&secret=");

            Assert.Equal(401, (Int32)resp.StatusCode);
        }
        finally
        {
            app.Delete();
        }
    }

    [Fact(DisplayName = "正确应用密钥可读取网关配置(StarGateway 路径回归)")]
    public async Task ValidSecret_Ok()
    {
        var app = CreateApp("gw_" + Rand.NextString(8), "gw-secret");
        try
        {
            var resp = await GetConfigAsync($"appId={app.Name}&secret=gw-secret");
            var body = await resp.Content.ReadAsStringAsync();

            Assert.NotEqual(401, (Int32)resp.StatusCode);
            Assert.False(body.IsNullOrEmpty());
        }
        finally
        {
            app.Delete();
        }
    }

    [Fact(DisplayName = "有效应用令牌可读取网关配置")]
    public async Task ValidToken_Ok()
    {
        var app = CreateApp("gw_" + Rand.NextString(8), "gw-secret");
        try
        {
            var client = _server.CreateClient();
            var rs = await client.PostAsync<LoginResponse>("app/login", new { AppId = app.Name, Secret = "gw-secret" });
            Assert.NotNull(rs?.Token);

            var resp = await client.GetAsync($"/Gateway/config?token={rs.Token}");
            Assert.NotEqual(401, (Int32)resp.StatusCode);
        }
        finally
        {
            app.Delete();
        }
    }
}