网站首页 网站源码
using Dpz.Core.Auth.Models;
using Dpz.Core.Auth.Service;
using Dpz.Core.EnumLibrary;
using Dpz.Core.Infrastructure;
using Dpz.Core.MongodbAccess;
using Dpz.Core.Public.Entity.Auth;
using Dpz.Core.Service;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using OpenIddict.Abstractions;
namespace Dpz.Core.Auth.Controllers;
[Authorize(nameof(Permissions.System))]
public class TokenController(
IOpenIddictTokenManager openIddictTokenManager,
IRepository<DpzToken> repository,
IRepository<DpzApplication> dpzApplicationRepository,
IPinCodeValidator pinCodeValidator
) : Controller
{
public async Task<IActionResult> Index()
{
var applications = await dpzApplicationRepository
.SearchFor(x => true)
.Select(x => new AuthApplicationModel(x.Id.ToString(), x.ClientId, x.DisplayName))
.ToListAsync();
return View(applications);
}
public async Task<IActionResult> Page(
string? userId = null,
string? clientId = null,
int page = 1,
int limit = 10
)
{
if (page < 1)
{
page = 1;
}
if (limit < 1)
{
limit = 1;
}
var filter = Builders<DpzToken>.Filter.Empty;
if (!string.IsNullOrWhiteSpace(userId))
{
filter &= Builders<DpzToken>.Filter.Eq(x => x.Subject, userId);
}
if (!string.IsNullOrWhiteSpace(clientId) && ObjectId.TryParse(clientId, out var appId))
{
filter &= Builders<DpzToken>.Filter.Eq(x => x.ApplicationId, appId);
}
var list = await repository
.SearchFor(filter)
.SortByDescending(x => x.Id)
.ToPagedListAsync(page, limit);
var data = list.Select(x => new PageTokenModel
{
Id = x.Id.ToString(),
ApplicationId = x.ApplicationId.ToString(),
AuthorizationId = x.AuthorizationId.ToString(),
ConcurrencyToken = x.ConcurrencyToken,
CreationDate = x.CreationDate,
ExpirationDate = x.ExpirationDate,
Payload = x.Payload,
Properties = x.Properties,
RedemptionDate = x.RedemptionDate,
ReferenceId = x.ReferenceId,
Status = x.Status,
Subject = x.Subject,
Type = x.Type,
})
.ToList();
var applicationIds = data.Select(x => ObjectId.Parse(x.ApplicationId)).ToHashSet();
var clientFilter = Builders<DpzApplication>.Filter.In(x => x.Id, applicationIds);
var applications = await dpzApplicationRepository
.SearchForAsync(clientFilter)
.ToListAsync();
data.ForEach(x =>
x.ApplicationName = applications
.Find(y => y.Id == ObjectId.Parse(x.ApplicationId))
?.DisplayName
);
return Json(new LayuiPageWarp<PageTokenModel>(data, list.TotalItemCount));
}
[HttpPost]
public async Task<IActionResult> RevokeByUser(string userId, string pinCode)
{
var (success, message) = await pinCodeValidator.ValidateAsync(User.NameIdentifier, pinCode);
if (!success)
{
return Json(ResponseResult.ToFail(message));
}
var count = await openIddictTokenManager.RevokeAsync(userId, null, null, null);
return Json(
count > 0
? ResponseResult.ToSuccess($"撤销{count}个应用令牌")
: ResponseResult.ToFail("撤销失败,请确认应用程序")
);
}
[HttpPost]
public async Task<IActionResult> RevokeByClient(string clientId, string pinCode)
{
var (success, message) = await pinCodeValidator.ValidateAsync(User.NameIdentifier, pinCode);
if (!success)
{
return Json(ResponseResult.ToFail(message));
}
var count = await openIddictTokenManager.RevokeAsync(null, clientId, null, null);
return Json(
count > 0
? ResponseResult.ToSuccess($"撤销{count}个应用令牌")
: ResponseResult.ToFail("撤销失败,请确认应用程序")
);
}
}
上述代码是一个 ASP.NET Core 控制器类 TokenController,用于管理与 OAuth 2.0 和 OpenID Connect 相关的令牌(Token)。该控制器主要提供了以下功能:
授权控制:
[Authorize(nameof(Permissions.System))] 特性,确保只有具有特定权限的用户才能访问该控制器中的操作。Index 方法:
Index 方法用于获取所有应用程序的列表,并将其传递给视图进行展示。它从 dpzApplicationRepository 中检索所有应用程序,并将其转换为 AuthApplicationModel 对象的列表。Page 方法:
Page 方法用于分页获取令牌(Token)数据。它接受用户 ID、客户端 ID、页码和每页限制作为参数。repository 中检索符合条件的令牌,并将其转换为 PageTokenModel 对象的列表。RevokeByUser 方法:
RevokeByUser 方法用于撤销特定用户的令牌。它首先验证用户提供的 PIN 码,如果验证失败,则返回失败的 JSON 响应。openIddictTokenManager.RevokeAsync 方法撤销与该用户相关的令牌,并返回撤销的令牌数量。RevokeByClient 方法:
RevokeByClient 方法用于撤销特定客户端的令牌。与 RevokeByUser 方法类似,它也会验证 PIN 码,并在成功后撤销与该客户端相关的令牌。这个控制器的主要功能是管理 OAuth 2.0 和 OpenID Connect 的令牌,包括列出应用程序、分页获取令牌、以及根据用户或客户端撤销令牌。它通过使用 MongoDB 作为数据存储,并结合 ASP.NET Core 的身份验证和授权机制,提供了一个安全的 API 接口。
