c# - Asp.net core 2.1 web api中的自定义授权

标签 c# asp.net asp.net-web-api dependency-injection autofac

我想拦截每个进入 api 的网络请求,在每个请求期间我想调用一个我编写的函数,它会告诉我用户有一个有效的未过期的许可证 key 。我需要做的几件事是能够识别用户,我可以通过打开 JWT token 来做到这一点我需要访问该 token ,我还需要能够从我的一个类中调用方法,即已经注册使用 autofac 进行注入(inject)。我知道我可以使用 Action 过滤器和中间件,但我没有太多使用这些的经验,我正在寻找最好的方法来做到这一点,甚至可以给我一些例子。哦,我还必须能够知道路线,有几个 API 方法可以免除此检查。如果检查感觉我显然要抛出请求,可能会抛出 401 错误或其他东西。

最佳答案

我强烈推荐 Neil Cummings 的 Udemy 类(class) Build an App with ASPNET Core and Angular From Scratch

sample solution包括 MIT 许可证。

这个 28 小时的类(class)和相关解决方案利用:

  • 用于身份验证的 JWT token 和 Microsoft.AspNetCore.Identity
  • IAsyncActionFilter 到:
    • 拦截网络请求
    • 阅读用户声明
    • 解决来自 Microsoft.Extensions.DependencyInjection

以下部分与您要完成的工作直接相关:

3.26 创建具体的授权库和注册方法

3.27 创建登录存储库方法

3.29 在我们的 Auth Controller 中创建 Register 方法

3.32 token 认证

客户端将 token 发送到服务器。服务器不使用数据库来验证用户,它验证 token 本身。

3.33 在API中创建登录方法

在此处将声明添加到 token :

AuthController.cs

public class AuthController : ControllerBase
{
    [HttpPost("login")]
    public async Task<IActionResult> Login(UserForLoginDto userForLoginDto)
    {
        …
        return Ok(new {
            token = GenerateJwtToken(appUser).Result,
            user = userToReturn});}
    }

    private async Task<string> GenerateJwtToken(User user)
    {
        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
            new Claim(ClaimTypes.Name, user.UserName)
        };

        var roles = await _userManager.GetRolesAsync(user);

        foreach (var role in roles)
        {
            claims.Add(new Claim(ClaimTypes.Role, role));
        }

        var key = new SymmetricSecurityKey(Encoding.UTF8
            .GetBytes(_config.GetSection("AppSettings:Token").Value));

        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);

        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(claims),
            Expires = DateTime.Now.AddDays(1),
            SigningCredentials = creds
        };

        var tokenHandler = new JwtSecurityTokenHandler();

        var token = tokenHandler.CreateToken(tokenDescriptor);

        return tokenHandler.WriteToken(token);
    }
}

3.34 使用认证中间件

JwtBearerDefaults.AuthenticationScheme 在此处向 DI 注册:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII
                        .GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
                    ValidateIssuer = false,
                    ValidateAudience = false
                };
            });
    }
}

4.39 Angular服务介绍

用户的 token 在成功登录后存储到浏览器的本地存储中:

auth.service.ts

export class AuthService {
    login(model: any) {
        return this.http.post(this.baseUrl + ‘login’, model).pipe(
            map((response: any) => {
                const user = response;
                if(user) { localStorage.setItem(‘token’, user.token);}}));}}

6.55 使用 Angular JWT 库解码 token

将解码 token 的属性添加到 authService.ts

13.134 使用 Action 过滤器

你可以:

  • 通过 Action Filter 中的 Claim 验证许可证 key

  • 通过ActionExecutingContext判断当前API路由

下面是一个从 Action Filter 中检索用户声明以及解析服务的示例:

public class LogUserActivity : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        var resultContext = await next();

        var userId = int.Parse(resultContext.HttpContext.User
            .FindFirst(ClaimTypes.NameIdentifier).Value);
        var repo = resultContext.HttpContext.RequestServices.GetService<IDatingRepository>();
        var user = await repo.GetUser(userId, true);
        user.LastActive = DateTime.Now;
        await repo.SaveAll();
    }
}

关于c# - Asp.net core 2.1 web api中的自定义授权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53643029/

相关文章:

c# - WPF ComboBox XML 绑定(bind)和 ViewModel 绑定(bind)?

c# - 如何配置空 ASP .NET 应用程序以将其发布到 IIS

c# - 搜索查询 IQueryable<> MVC

javascript - 验证具有前两位数字和一个字母的字段

c# - 如何从 C# 方法返回 Json 对象

java - 无法执行从 Android 应用程序到 ASP.NET WebAPI 的 HTTPPost 请求

c# - INotifyCollectionChanged 没有更新 UI

c# - 一个可以在windows任务栏中运行的简单应用程序

c# - 找不到 ASP.NET IserviceCollection AddIdentity

javascript - 如何手动设置剑道寻呼机的总数