I'm developing 3rd party API connector bridge in class library NOT in ASP.NET.
User Levels
API has 3 user levels, lets say:
- UserGoer
- UserDoer
- UserMaker
Service Restriction
Each API operation can work with one or multiple user level roles. For example, lets assume operations and reachable user levels as follows;
- JokerService (reachable by UserGoer, UserMaker)
- PokerService (reachable by UserGoer, UserDoer)
- MokerService (reachable by UserGoer, UserDoer, UserMaker)
If UserDoer requests for JokerService, API returns bad request. JokerService is only reachable for UserGoer and UserMaker. So, I want to restrict and throw an exception.
User Token Structure
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
}
Customized Authentication Attribute
public class AuthenticationFilter : Attribute
{
public TokenType[] TokenTypes { get; private set; }
public AuthenticationFilter(params TokenType[] TokenTypes)
{
this.TokenTypes = TokenTypes;
}
}
Example Service
[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);
}
In summary, JokerService can be executable by UserGoer and UserMaker. UserDoer has no permission for this service.
As you see the the usage of AuthenticationFilter
attribute, I'm getting custom attributes in the constructor, because i want to know what IToken
is. If there is an irrelevant "User Authentication Token" type that is passed as parameter (IToken), program should be throw an exception.
This is my solution, do you think is there any best practice for my problem?
Thank you for your help.
Aucun commentaire:
Enregistrer un commentaire