Files
yunhai.netcore.tool/BasePlatformDotnet/tests/Yh.Platform.Auth.Tests/AuthContextTests.cs
T
2026-09-02 09:38:45 +08:00

162 lines
5.1 KiB
C#

using System.Security.Claims;
using Yh.Platform.Abstractions;
using Yh.Platform.Auth;
using Xunit;
namespace Yh.Platform.Auth.Tests;
/// <summary>CAS serviceValidate 响应 XML 用户提取对拍(对齐 Java CasServiceTicketValidator)。</summary>
public class CasServiceTicketValidatorTests
{
[Fact]
public void 成功响应_提取cas_user()
{
var xml = """
<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">
<cas:authenticationSuccess>
<cas:user>zhangsan</cas:user>
</cas:authenticationSuccess>
</cas:serviceResponse>
""";
Assert.Equal("zhangsan", CasServiceTicketValidator.ExtractUser(xml));
}
[Fact]
public void 带属性容错_提取cas_user()
{
var xml = "<cas:serviceResponse><cas:authenticationSuccess><cas:user index=\"0\">lisi</cas:user></cas:authenticationSuccess></cas:serviceResponse>";
Assert.Equal("lisi", CasServiceTicketValidator.ExtractUser(xml));
}
[Fact]
public void 失败响应_返回null()
{
var xml = """
<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">
<cas:authenticationFailure code="INVALID_TICKET">
Ticket ST-1856339 not recognized
</cas:authenticationFailure>
</cas:serviceResponse>
""";
Assert.Null(CasServiceTicketValidator.ExtractUser(xml));
}
[Theory]
[InlineData("")]
[InlineData(null)]
[InlineData("<cas:serviceResponse></cas:serviceResponse>")]
public void 无用户节点或空输入_返回null(string? xml)
{
Assert.Null(CasServiceTicketValidator.ExtractUser(xml));
}
[Fact]
public async Task 未配置CAS地址_抛AuthException()
{
var validator = new CasServiceTicketValidator("");
var ex = await Assert.ThrowsAsync<AuthException>(() => validator.ValidateAsync("ST-1", "http://app/cb"));
Assert.Contains("cas-server-url-prefix", ex.Message);
}
}
public class BoaUserContextTests
{
[Fact]
public async Task 异步流内可读取_请求结束清理()
{
Assert.Null(BoaUserContext.Get());
Assert.Null(UserContextHolder.Get());
BoaUser? seenInChild = null;
var user = new BoaUser(1001, "zhangsan", "张三");
BoaUserContext.Set(user);
UserContextHolder.Set(new LoginUser("1001") { LoginName = "zhangsan", DisplayName = "张三" });
await Task.Run(() =>
{
// AsyncLocal 值随执行上下文流入子任务
seenInChild = BoaUserContext.Get();
});
Assert.Same(user, seenInChild);
Assert.Equal("zhangsan", UserContextHolder.Get()?.LoginName);
BoaUserContext.Clear();
UserContextHolder.Clear();
Assert.Null(BoaUserContext.Get());
Assert.Null(UserContextHolder.Get());
}
[Fact]
public void LoginUser_属性封装()
{
var login = new LoginUser("1001")
{
LoginName = "zhangsan",
DisplayName = "张三",
AppKey = "app-001",
};
Assert.Equal("1001", login.UserId);
Assert.Equal("zhangsan", login.LoginName);
Assert.Equal("张三", login.DisplayName);
Assert.Equal("app-001", login.AppKey);
}
}
public class UserContextMiddlewareTests
{
private sealed class StubProvider : IUserDetailsProvider
{
public BoaUser? User { get; set; } = new(1001, "zhangsan", "张三");
public Task<BoaUser?> GetByLoginNameAsync(string loginName, CancellationToken ct = default)
=> Task.FromResult(User);
}
private static HttpContext HttpContextWithLogin(string loginName)
{
var identity = new ClaimsIdentity("CAS");
identity.AddClaim(new Claim("loginName", loginName));
var context = new DefaultHttpContext();
context.User = new ClaimsPrincipal(identity);
return context;
}
[Fact]
public async Task 认证请求_中间件写入上下文_业务管道内可读()
{
var provider = new StubProvider();
BoaUser? seen = null;
LoginUser? seenLogin = null;
var middleware = new UserContextMiddleware(_ =>
{
seen = BoaUserContext.Get();
seenLogin = UserContextHolder.Get();
return Task.CompletedTask;
});
await middleware.InvokeAsync(HttpContextWithLogin("zhangsan"), provider);
Assert.NotNull(seen);
Assert.Equal(1001, seen!.Id);
Assert.Equal("zhangsan", seenLogin?.LoginName);
Assert.Equal("张三", seenLogin?.DisplayName);
// 请求结束后必须清空,防串扰
Assert.Null(BoaUserContext.Get());
Assert.Null(UserContextHolder.Get());
}
[Fact]
public async Task 未认证请求_不写上下文直接放行()
{
var provider = new StubProvider();
var middleware = new UserContextMiddleware(_ => Task.CompletedTask);
var context = new DefaultHttpContext(); // 匿名
await middleware.InvokeAsync(context, provider);
Assert.Null(BoaUserContext.Get());
Assert.Null(UserContextHolder.Get());
}
}