Аутентификация JWT Как проверить http-запросы в отдельном проекте API, а не в проекте AuthServer - PullRequest
0 голосов
/ 12 апреля 2019

После прочтения нескольких статей особенно это

Я создал собственное решение ASP.NET Core, которое имеет

1 проект (AuthServer) для Authentication и Authorisation и

1 проект (WebApi) для остальных API во всех моих проектах.

Вопрос: Как проверить http-запросы в моем проекте WebApi?

Я знаю, что как только пользователь проходит аутентификацию, клиент будет держать токен, и для последующих запросов все они должны передать int Token и на стороне сервера он каким-то образом проверяет эти запросы с помощью этого фрагмента кода, который находится в Startup.cs для проекта AuthServer:

services.AddAuthentication(x =>
        {
            x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(x=> {
            x.Events = new JwtBearerEvents
            {
                OnTokenValidated = context =>
                {
                    var userService = context.HttpContext.RequestServices.GetRequiredService<IUserService>();
                    var userId = context.Principal.Identity.Name;
                    var user = userService.GetById(userId);
                    if(user == null)
                    {
                        context.Fail("Unauthorized");
                    }
                    return Task.CompletedTask;
                }
            };
            x.RequireHttpsMetadata = false;
            x.SaveToken = true;
            x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(key),
                ValidateIssuer = false,
                ValidateAudience = false
            };

        });

Но что нужно сделать для проекта WebApi, чтобы проверить токен? Я бы предположил, что это будет не просто размещение аннотации ( [Authorize] ) на контроллере или действия вроде:

[Authorize]
[Route("api/[controller]")]
[ApiController]
public class ProductsController : ControllerBase
{ ....}

Тогда что мне нужно сделать, чтобы проверить токен в моем проекте WebApi? Вызывая конечную точку Authenticate в моем AuthServer проекте каждый раз, когда приходит запрос, а затем выполняю код в WebApi?

Ответы [ 2 ]

1 голос
/ 12 апреля 2019

Я предполагаю, что вы хотите запустить 2 отдельных приложения ASP.NET. Вы можете проверять запросы, поступающие на WebApi, отправляя http-запросы на AuthServer. Вы можете создать собственный атрибут, который будет выполнять работу. В проекте WebApi:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Primitives;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Security.Claims;
using System.Threading.Tasks;

namespace YourNamespace
{
    public class YourCustomAttribute : TypeFilterAttribute
    { 
        public YourCustomAuthAttribute(
            : base(typeof(AuthFilter))
        {
            Arguments = new object[] {
               // arguments gets passed to AuthFilter contructor,

            };
        }
    }

    public class AuthFilter : IAsyncAuthorizationFilter
    {
        private static readonly HttpClient http = new HttpClient();

        public AuthFilter()
        {
        }

        //Change it to fit your logic
        public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
        {
            var authorizationHeader = context.HttpContext.Request.Headers["Authtorization"];
            if (authorizationHeader == StringValues.Empty)
            {
                context.Result = new UnauthorizedResult();
            }
            else
            {
                var response = await http.GetAsync(
                    "your AuthServer address/login/?token=" + authorizationHeader.ToString(),
                    HttpCompletionOption.ResponseHeadersRead //because we want only status code
                );
                if (response.StatusCode != System.Net.HttpStatusCode.OK)
                {
                    context.Result = new ForbidResult();
                }
            }
        }
    }
}

Предполагается, что у вас есть следующая конечная точка в LoginController в проекте AuthServer

[HttpGet]
public IActionResult ValidateToken(string token)
{
   //your logic here
}

Использование атрибутов такое же, как [Authorize].

Проверьте эту ссылку тоже (я использовал некоторый код из нее) https://www.red -gate.com / simple-talk / dotnet / net-development / jwt-authentication-microservices-net / . Показано, как проверить токен JWT вручную.

Вам также может понадобиться настроить CORS в проекте AuthServer, чтобы WebApi мог отправлять запросы. Startup.cs

public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(options =>
            {
                options.AddPolicy("AllowAllHeaders",
                      builder =>
                      {
                          builder.AllowAnyOrigin()
                                 .AllowAnyHeader()
                                 .AllowAnyMethod();
                      });
            });
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider)
        {
            app.UseCors("AllowAllHeaders");
        }
0 голосов
/ 17 апреля 2019

После нескольких часов чтения я обнаружил статью, в которой говорилось о том, следует ли отделить AuthServer от вашего API-сервера.

В крупных коммерческих проектах, безусловно, лучше разделять их, но в моем случае это всего лишь мой побочный проект, поэтому я закончил собирать их вместе, чтобы сэкономить энергию.

...