如果我直接进入它,我已经建立了一个
RESTful
服务(WebAPI
V2)与basic authentication
......一切都按预期工作,但我非常不确定如何从ClaimsPrincipal
中检索值.我读过很多文章,但都指向在Identity
.中使用第三方库和/或
.Net
为了保持简短和甜美,我有一个
Attribute
执行必要的逻辑和一个自定义 authenticateService
指向我的 data store
.
我有一个
n-tier architecture
:
所以我想第一个问题是,我怎样才能从
ClaimsPrincipal
中读取值? (道歉第一次使用索赔)
注意:我希望它能在每次请求时触发,不会有
session
。
创建和验证用户的一些逻辑(内部
Attribute
)
using (var authService = new AuthenticateService())
{
var client = await _authenticateService.AuthenticateAsync(
apiKey,
password);
if (client != null)
{
// Create a ClaimsIdentity with all the claims for this user.
Claim apiKeyClaim = new Claim("API Key", apiKey);
Claim clientNameClaim = new Claim(ClaimTypes.Name, client.ClientName);
Claim clientKeyClaim = new Claim("Client Key", client.ClientKey);
List<Claim> claims = new List<Claim>
{
apiKeyClaim,
clientNameClaim,
clientKeyClaim
};
// important to set the identity this way, otherwise IsAuthenticated will be false
// see: http://leastprivilege.com/2012/09/24/claimsidentity-isauthenticated-and-authenticationtype-in-net-4-5/
ClaimsIdentity identity = new ClaimsIdentity(claims, "Basic");
// AuthenticationTypes.Basic
var principal = new ClaimsPrincipal(identity);
return principal;
//var principal = new GenericPrincipal(new GenericIdentity("CustomIdentification"),
// new[] { "SystemUser" });
//return principal;
}
else
{
return null;
}
}
在我的
API controller
中访问声明值:
[IdentityBasicAuthentication]
[Authorize]
[RoutePrefix("api")]
public class OrderController : ApiController
{
private IOrderService _orderService;
public OrderController(IOrderService orderService)
{
_orderService = orderService;
}
// POST api/<controller>
[HttpPost]
[Route("order")]
public async Task<IHttpActionResult> Post([FromBody]Models.Model.Order order)
{
var modelResponse = new ModelResponse<Models.Model.Order>(order);
if (order == null)
return BadRequest("Unusable resource.");
if (!modelResponse.IsModelValid())
return this.PropertiesRequired(modelResponse.ModelErrors());
try
{
//Create abstracted Identity model to pass around layers
// Access Claim values here
//OR can I use Claims in other layers without creating an abstracted model to pass through.
await _orderService.AddAsync(order);
}
catch (System.Exception ex)
{
return InternalServerError();
}
finally
{
_orderService.Dispose();
}
return Ok("Order Successfully Processed.");
}
}
非常感谢您花时间阅读本文,希望“有人”可以指导/帮助我阅读声明值和/或传递层的最佳方法。
问候,
您可以通过这种方式访问声明。在你的控制器方法中:
try
{
// ...
var claimsIdentity = (ClaimsIdentity)this.RequestContext.Principal.Identity;
foreach(var claim in claimsIdentity.Claims)
{
// claim.value;
// claim.Type
}
// ...
}
@User.Claims.FirstOrDefault(c => c.Type == "Currency").Value
我更喜欢 LINQ 来访问 可以在这里找到: https://msdn.microsoft.com/en-us/library/ee517271.aspx?f=255&MSPPError=-2147217396
用于查看 Azure Functions v3 (netcore3.1) 中的所有权限和声明。从各种 SO 文章中拼凑而成。
...
using System.Security.Claims;
using System.Linq;
...
[FunctionName("AdminOnly")]
public static async Task<IActionResult> RunAdminOnly(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "test")] HttpRequest req,
ILogger log,
ClaimsPrincipal claimsID)
{
string perms ="";
foreach(var h in req.Headers)
{
perms += $"{h.Key}:{String.Join(",", h.Value)}" + "\n";
}
string claims = "";
foreach (Claim claim in claimsID.Claims)
{
claims += $"{claim.Type} : {claim.Value} \n";
}
string claimDetail = "";
Claim? appRole = claimsID.Claims.FirstOrDefault(c => c.Type == "extension_AppRole"); // custom claim
claimDetail += appRole?.Value.ToString();
return new OkObjectResult(perms + "\n\n" + claims + "\n\n" + claimDetail);
}
对于那些想知道如何从 .net7 aspcore 中的 ClaimsPrincipal 获取主题 ID 的人来说,可以像这样轻松完成
var claim = principal.FindFirst(Claims.Subject);
var id = Guid.Parse(claim?.Value ?? ""); // or cast/parse it to the expected type