Simple token based authentication/authorization in asp.net core for Mongodb datastore

|▌冷眼眸甩不掉的悲伤 提交于 2019-11-27 14:27:24

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 rc2btw):

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()
{
} 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!