c#中类库类和函数的自定义属性



我正在类库中开发第三方API连接器桥NOT在ASP.NET .

用户级别

API有3个用户级别,比如:

  • UserGoer
  • UserDoer
  • UserMaker

服务限制

每个API操作可以使用一个或多个用户级角色。例如,我们假设操作和可访问的用户级别如下:

  • JokerService(可由UserGoer, UserMaker访问)
  • PokerService(可由UserGoer, UserDoer访问)
  • MokerService(可访问的UserGoer, UserDoer, UserMaker)

如果UserDoer请求JokerService, API返回错误请求。JokerService只对UserGoer和UserMaker可用。所以,我想限制并抛出一个异常。

用户Token结构

public interface IToken
{
string AccessToken { get; set; }
string RefreshToken { get; set; }
}
public class AuthenticationToken : IToken
{
[JsonProperty("access_token")]
public string AccessToken { get; set; }
[JsonProperty("refresh_token")]
public string RefreshToken { get; set; }
}

public class UserGoerAuthenticationToken : AuthenticationToken
{
}
public class UserDoerAuthenticationToken : AuthenticationToken
{
}
public class UserMakerAuthenticationToken : AuthenticationToken
{
}
Enum>
public enum TokenType
{
Undefined = 0,
UserGoer = 1,
UserDoer = 2,
UserMaker = 3
}

自定义认证属性

public class AuthenticationFilter : Attribute
{
public TokenType[] TokenTypes { get; private set; }
public AuthenticationFilter(params TokenType[] TokenTypes)
{
this.TokenTypes = TokenTypes;
}
}

示例服务

[AuthenticationFilter(TokenType.UserGoer, TokenType.UserMaker)]
internal class JokerService : BaseService<JokerEntity>
{
public JokerService(IToken AuthenticationToken) : base(AuthenticationToken)
{
var tokenTypes = 
(typeof(JokerService).GetCustomAttributes(true)[0] as AuthenticationFilter)
.TokenTypes;
bool throwExceptionFlag = true;
foreach (var item in tokenTypes)
{
// Check AuthenticationToken is UserGoer or UserMaker by StartsWith function
if (AuthenticationToken.GetType().Name.StartsWith(item.ToString()))
{
throwExceptionFlag = false;
break;
}
}
if (throwExceptionFlag)
throw new Exception("Invalid Authentication Token");
}
public JokerEntity Create(RequestModel<JokerEntity> model) => base.Create(model);
public JokerEntity Update(RequestModel<JokerEntity> model) => base.Update(model);
public JokerEntity Get(RequestModel<JokerEntity> model) => base.Get(model);
public List<JokerEntity> List(RequestModel<JokerEntity> model) => base.List(model);
}
总而言之,JokerService可以被UserGoer和UserMaker执行。UserDoer没有此服务的权限。

正如您看到的AuthenticationFilter属性的使用,我在构造函数中获得自定义属性,因为我想知道IToken是什么。如果存在不相关的"用户身份验证令牌";作为参数传递的类型(IToken),程序应该抛出异常。

这是我的解决方案,你认为有什么最好的做法,我的问题?

谢谢你的帮助。

有趣的问题。在建设性批评中,我最初的想法是,特定类通过属性接受的令牌是在编译时决定的,无法更改。但是,权限检查发生在每个对象的构造上。

您可以使用设置tokenTypes变量的static构造函数来防止这种情况。静态构造函数总是在实例构造函数之前运行。这也是确保tokenTypes永远不为空(在没有自定义属性的情况下)的好地方。

同样,通过tokenTypes的循环可能是一个接受ITokentokenTypes的函数,更重要的是,可能存在于BaseService.cs中。编写一次逻辑将使将来某些需求需要对其进行更改时更容易维护。:)

参见:https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-constructors

希望对你有帮助。

最新更新