If I get straight into it, I've built a RESTful
Service (WebAPI
V2) with basic authentication
... All is working as expected but I'm very unsure on how to retrieve values from ClaimsPrincipal
. I've read many articles but all point to using third party libraries And/or Identity
in .Net
.
To keep it short and sweet, I have an Attribute
performing necessary logic and a custom authenticateService
which points to my data store
.
I have an n-tier architecture
:
So I guess the first question is, how can I read the values from ClaimsPrincipal
? (Apologies first time using Claims)
To Note: I'm expecting this to fire on each request, there will be no session
.
Some logic that creates and authenticates the user (Inside 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;
}
}
Accessing Claim Values in my 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.");
}
}
Really appreciate your time reading this, hopefully "someone" can direct/help me reading claim values and/or best approach to passing around layers.
Regards,
ClaimsPrincipal exposes a collection of identities, each of which is a ClaimsIdentity. In the common case, this collection, which is accessed through the Identities property, will only have a single element.
The ClaimsIdentity class is a concrete implementation of a claims-based identity; that is, an identity described by a collection of claims.
Claims can be created from any user or identity data which can be issued using a trusted identity provider or ASP.NET Core identity. A claim is a name value pair that represents what the subject is, not what the subject can do.
You can access to claims this way. In your controller method:
try
{
// ...
var claimsIdentity = (ClaimsIdentity)this.RequestContext.Principal.Identity;
foreach(var claim in claimsIdentity.Claims)
{
// claim.value;
// claim.Type
}
// ...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With