-
-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support authorization on operation level #561
Comments
@Matasx: This will be one of the next features to be implemented - if I am not mistaken, role based authorization was on your wishlist as well. Maybe you can find some time to review this draft and the proposed API. |
Yes I can certainly provide my 50c. I would keep it as simple as possible. So one possible solution is to extend IUser with Authenticator method can remain unchanged, as the function returns IUser - now extended with the Roles collection. If undesired, we can perhaps add method overload that returns IUser extended with the Roles property (so that developer who don't use role based auth are not obligated to provide Roles property). Then we can provide one attribute RequireRole, usage: public class MyService
{
[ResourceMethod]
[RequireRole("PAID")]
public IResponse PaidOnly() { ... }
//OFC devs can use e.g. static class with const names for roles
[ResourceMethod]
[RequireRole(Roles.Paid)]
public IResponse PaidOnly() { ... }
} If developers wish to require more roles for one endpoint, they would simply add multiple attributes (imo more clear than array of roles in one attribute). Here is example of what developers might use to resolve effective roles: public static class Roles
{
//User has any paid subscription -> can update profile, etc.
public const string Paid = "PAID";
// Features
public const string Basic = "BASIC";
public const string Advanced = "ADVANCED";
public const string Premium = "PREMIUM";
// Roles
public const string User = "USER";
public const string Admin = "ADMIN";
// Web UI roles
public const string WebUiUser = "WEB";
public const string WebUiAdmin = "WEB_ADMIN";
public const string Discord = "DISCORD";
public const string TradingView = "TRADING_VIEW";
public static readonly ImmutableHashSet<string> DiscordRoles = [Basic];
public static readonly ImmutableHashSet<string> TradingViewRoles = [Advanced, Premium];
private static readonly Dictionary<string, IImmutableList<string>> _impliedRoles = new()
{
{ User, ImmutableList.Create(WebUiUser) },
{ Admin, ImmutableList.Create(User, WebUiAdmin, Premium) },
{ Premium, ImmutableList.Create(Advanced) },
{ Advanced, ImmutableList.Create(Basic, TradingView) },
{ Basic, ImmutableList.Create(Paid, Discord) }
};
public static ISet<string> GetEffectiveRoles(ISet<string> grantedRoles)
{
if (grantedRoles.Count == 0) return grantedRoles;
HashSet<string> roles = new(grantedRoles);
var implied = GetEffectiveRoles(roles
.SelectMany(x =>
{
if (_impliedRoles.TryGetValue(x, out var implied))
{
return implied;
}
return [];
}).ToHashSet());
roles.UnionWith(implied);
return roles;
}
} |
Thanks, I like the idea of having a simplified role-based authorization model. I think both features mix pretty well - an underlying With this I propbably can make the public class RequireRoleAttribute(string role): InterceptWithAttribute<RoleBasedAuthorization> { }
public class RoleBasedAuthorization : IOperationInterceptor { } |
As a developer of a web service, I would like to control authorization on operation instead of API level, so that I do not need to handle the authorization within the operation and can simpliy annotate my methods.
Example
Acceptance criteria
The text was updated successfully, but these errors were encountered: