C
C#14mo ago
Esa

✅ Help with authentication/authorization for my application with .net 7

Hi, I was hoping someone could help me out with Claims/Identity/Roles. I have an application with a couple system users. These users pass an API Key along their requests. Through this api key, I find their actual user in a DB. In addition to the User table, I have a Feature table and a UserFeature table that connects a user with some feature of the application. This is how I can see that userA has access to the feature CustomerSearch for example. I would like to move away from gnarly if-checks in the controller to see if a UserFeature entity exists with the userId, and instead make use of the annotations found in .net on the controller endpoints so that I can simply annotate that a method requires a certain feature. Any ideas?
16 Replies
Esa
EsaOP14mo ago
Reading up on claims on microsoft docs this doesn't seem to fit with how identity / authentication is commonly done I'd appreciate any thoughts on this topic as I have never done "proper" authentication before
Unknown User
Unknown User14mo ago
Message Not Public
Sign In & Join Server To View
Esa
EsaOP14mo ago
It's actually super straight forward. Just an ordinary backend service with an api (web api project .net 7.0) with the following data structure for the user / features part:
public class Feature
{
public int Id { get; set;}
public string Name { get; set;}
public string Description { get; set;}

public virtual ICollection<UserFeature> UserFeatures { get; set; }
}

public class User
{
public int Id { get; set; }

public virtual ICollection<UserFeature> UserFeatures { get; set; }
}

public class UserFeature
{
public int Id { get; set;}
public int UserId { get; set;}
public int FeatureId { get;set;}

public virtual User User { get; set; }
}


public class MyDbContext : DbContext
{
public DbSet<User> Users;
public DbSet<UserFeature> UserFeatures;
public DbSet<Feature> Features;
}
public class Feature
{
public int Id { get; set;}
public string Name { get; set;}
public string Description { get; set;}

public virtual ICollection<UserFeature> UserFeatures { get; set; }
}

public class User
{
public int Id { get; set; }

public virtual ICollection<UserFeature> UserFeatures { get; set; }
}

public class UserFeature
{
public int Id { get; set;}
public int UserId { get; set;}
public int FeatureId { get;set;}

public virtual User User { get; set; }
}


public class MyDbContext : DbContext
{
public DbSet<User> Users;
public DbSet<UserFeature> UserFeatures;
public DbSet<Feature> Features;
}
So I have EFCore and regular controllers currently what I do is inject the DbContextFactory to the controllers which have to create a context and query for a user with a matching token, then query the userfeatures to see if they have the feature that the endpoint requires thats it the users are system users so they never perform any operations like forget password, reset password etc that i see mentioned in the Identity docs they simply pass a token we assigned to them ages ago
if (!Request.Headers.TryGetValue("ApiKey", out StringValues tokenValues))
return BadRequest("Found no token in headers");
if (!Request.Headers.TryGetValue("ApiKey", out StringValues tokenValues))
return BadRequest("Found no token in headers");
that's how i receive the apikey in the controllers, i believe this should cover the current solution sufficiently I saw there was some annotations I could add onto controllers to check for Claims ideally I'd associate a Feature with a user such that a Feature can be mapped to a claim
Accord
Accord14mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Esa
EsaOP14mo ago
Anybody else have some thoughts on this topic?
Pobiega
Pobiega14mo ago
You should probably make your own AuthenticationHandler that does the DB lookup and registers claims based on the database results RemoteAuthenticationHandler<T> is the base class iirc or well, perhaps remote isnt the right one here
Esa
EsaOP14mo ago
hmm
Pobiega
Pobiega14mo ago
AuthenticationHandler<T> alternatively just IAuthenticationHandler and IAuthenticationRequestHandler Auth is non trivial 🙂
Esa
EsaOP14mo ago
okay, this will allow me to do the role stuff on controller methods?
Pobiega
Pobiega14mo ago
Based on a brief reading, wouldn't claims be better?
Esa
EsaOP14mo ago
I dont know about any of this stuff maybe?
Pobiega
Pobiega14mo ago
roles are stuff like "Im an admin" claims are more granular like, "I can administrate user messages"
Esa
EsaOP14mo ago
ah then that is exactly what i need Ok, so something that scans db for existing users and adds them where needed with regards to the claims?
Pobiega
Pobiega14mo ago
well, you'd extract the API key from the request as part of the handler then look up the correct things that user can access and issue claims for each of them
Esa
EsaOP14mo ago
okay, I'll have a look at this 🙂 Thanks @Pobiega , this was easy to implement and seems to do the trick !solved
MODiX
MODiX14mo ago
That command had an error
UnknownCommand: Unknown command.
Remove your reaction to delete this message
Want results from more Discord servers?
Add your server