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

前端 未结 2 413
南笙
南笙 2020-12-01 17:20

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

相关标签:
2条回答
  • 2020-12-01 17:43

    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.

    0 讨论(0)
  • 2020-12-01 17:46

    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()
    {
    } 
    
    0 讨论(0)
提交回复
热议问题