I need to implement pretty simple auth mechanizm with basically 2 roles: Owners
and Users
. And I think that having Enum for that will be enough. Ap
Let me clarify a little @Adem's answer. You need to to implement custom middleware in specific way. There is 3 abstract classes that need to be implemented to implementing this (answer is correct for asp.net core rc2
btw):
Microsoft.AspNetCore.Builder.AuthenticationOptions
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware<TOptions>
Microsoft.AspNetCore.Authentication.AuthenticationHandler<TOptions>
and then add this middleware to your startup class.
Code example:
public class TokenOptions : AuthenticationOptions
{
public TokenOptions() : base()
{
AuthenticationScheme = "Bearer";
AutomaticAuthenticate = true;
}
}
public class AuthMiddleware : AuthenticationMiddleware<TokenOptions>
{
protected override AuthenticationHandler<TokenOptions> CreateHandler()
{
return new AuthHandler(new TokenService());
}
public AuthMiddleware(RequestDelegate next, IOptions<TokenOptions> options, ILoggerFactory loggerFactory, UrlEncoder encoder) : base(next, options, loggerFactory, encoder)
{
}
}
public class AuthHandler : AuthenticationHandler<TokenOptions>
{
private ITokenService _tokenService;
public AuthHandler(ITokenService tokenService)
{
_tokenService = tokenService;
}
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
string token = null;
AuthenticateResult result = null;
string token = Helper.GetTokenFromHEader(Request.Headers["Authorization"]);
// If no token found, no further work possible
if (string.IsNullOrEmpty(token))
{
result = AuthenticateResult.Skip();
}
else
{
bool isValid = await _tokenService.IsValidAsync(token);
if (isValid)
{
//assigning fake identity, just for illustration
ClaimsIdentity claimsIdentity = new ClaimsIdentity("Custom");
var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Name, "admin"));
claims.Add(new Claim(ClaimTypes.NameIdentifier, "admin"));
claims.Add(new Claim(ClaimTypes.Role, "admin"));
ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
result =
AuthenticateResult.Success(new AuthenticationTicket(claimsPrincipal,
new AuthenticationProperties(), Options.AuthenticationScheme));
}
else
{
result = AuthenticateResult.Skip();
}
}
return result;
}
}`
p.s. The code is just for illustration of idea. You will need to implement your own handler of course.
You can use custom middleware
to authenticate user and set claims
(name, roles etc.).
I will try to write a simple middleware
:
First create a middlware
class
:
public class CustomMiddleware
{
private readonly RequestDelegate _next;
private readonly UserRepository _userRepository;
public CustomMiddleware(RequestDelegate next, UserRepository userRepository)
{
_next = next;
_userRepository = userRepository;
}
public async Task Invoke(HttpContext context)
{
string token = context.Request.Headers["Token"];
var user = _userRepository.Get(token);
ClaimsIdentity claimsIdentity = new ClaimsIdentity("Custom");
var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Name, "admin"));
claims.Add(new Claim(ClaimTypes.NameIdentifier, "admin"));
foreach(var role in user.Roles)
{
claims.Add(ClaimTypes.Role, role);
}
ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
context.User = claimsPrincipal;
await _next(context);
}
}
Then use middleware
in Startup.cs
like this:
public void Configure(IApplicationBuilder app)
{
app.UseMiddleware<CustomMiddleware>();
...
}
Finally use Authorize
attribute:
[Authorize(Roles = "Users")]
public IActionResult Index()
{
}