ASP.NET Core 1.0 OAuth-сервер с использованием Openiddict

oauth asp.net-core asp.net-core-mvc asp.net-core-1.0 openiddict

2339 просмотра

2 ответа

2183 Репутация автора

Я хотел бы использовать OAuth Openiddict для защиты конечных точек API в моем веб-приложении ASP.NET Core 1.0. Эти apiконечные точки будут называться по телефону приложения и пользователи должны войти в систему с именем пользователя и паролем.

Поток идет так:

  • Пользователь может зарегистрироваться и войти через веб-приложение: https://www.domain.com
  • Пользователь устанавливает приложение телефона, и они могут войти и зарегистрироваться, используя приложение телефона. Вход, регистрация и доступ к данным осуществляется через apiконечные точки: Пример:https://www.domain.com/api/service/getsomedata

Как настроить OAuth Openiddict, чтобы защитить конечные точки API с помощью OAuth?

Автор: user2818430 Источник Размещён: 18.07.2016 07:29

Ответы (2)


5 плюса

26325 Репутация автора

Решение

Как настроить OAuth Openiddict, чтобы защитить конечные точки API с помощью OAuth?

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

Вот что я бы порекомендовал:

Создайте новый контроллер AccountController/ RegistrationControllerAPI, отвечающий за создание новых учетных записей:

Поскольку на данном этапе учетная запись пользователя не существует, вы не можете использовать токен аутентификации здесь (так же, как AccountController.Registerшаблон по умолчанию не может требовать аутентификации куки-файлов до регистрации пользователя).

Сконфигурируйте OpenIddict, чтобы включить конечную точку токена и разрешить предоставление учетных данных пароля владельца ресурса:

services.AddOpenIddict<ApplicationDbContext>()
    // Disable the HTTPS requirement during development.
    .DisableHttpsRequirement()

    // Enable the token endpoint, required to use
    // the resource owner password credentials grant.
    .EnableTokenEndpoint("/connect/token")

    // Enable the password and the refresh token flows.
    .AllowPasswordFlow()
    .AllowRefreshTokenFlow();

Используйте промежуточное программное обеспечение для проверки OAuth2 для защиты ваших API:

Чтобы включить аутентификацию токена, AspNet.Security.OAuth.Validationобратитесь к пакету 1.0.0-alpha2-final и добавьте его app.UseOAuthValidation()ранее app.UseMvc(). Чтобы сделать аутентификацию обязательной, просто используйте [Authorize]атрибут, как если бы вы использовали аутентификацию куки.

Не стесняйтесь играть с этим образцом . Он не использует мобильное приложение для клиентской части, но вы должны легко понять, как оно работает.

Для получения дополнительной информации вы также можете прочитать это сообщение в блоге, написанное Майком Русосом для блога Microsoft .NET Web Development and Tools: Аутентификация на токене на предъявителя в ASP.NET Core

Автор: Kévin Chalet Размещён: 19.07.2016 06:03

1 плюс

2183 Репутация автора

Хорошо, спасибо @Pinpoint за указание на правильное направление.

Однако вот моя конфигурация Startup.cs:

   public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

        if (env.IsDevelopment())
        {
            // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
            builder.AddUserSecrets();
        }

        builder.AddEnvironmentVariables();
        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

        services.AddIdentity<ApplicationUser, ApplicationRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

        services.AddOpenIddict<ApplicationUser, ApplicationRole, ApplicationDbContext>()
          .DisableHttpsRequirement()
          .EnableTokenEndpoint("/connect/token")
          .AllowPasswordFlow()
          .AllowRefreshTokenFlow()
          .UseJsonWebTokens();

        services.AddMvc();

        // Add application services.
        services.AddTransient<IEmailSender, AuthMessageSender>();
        services.AddTransient<ISmsSender, AuthMessageSender>();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {


        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
            app.UseBrowserLink();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();      

        app.UseIdentity();

        app.UseOpenIddict();

        app.UseJwtBearerAuthentication(new JwtBearerOptions
        {
            AutomaticAuthenticate = true,
            AutomaticChallenge = true,
            RequireHttpsMetadata = false,
            Audience = "http://localhost:24624/",
            Authority = "http://localhost:24624/"
        });


        // Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

ApplicationDbContext.cs:

  public class ApplicationDbContext : OpenIddictDbContext<ApplicationUser, ApplicationRole>
{
    public ApplicationDbContext(DbContextOptions options)
        : base(options)
    {
        Database.EnsureCreated();
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        // Customize the ASP.NET Identity model and override the defaults if needed.
        // For example, you can rename the ASP.NET Identity table names and more.
        // Add your customizations after calling base.OnModelCreating(builder);
    }
}

ApplicationRole.cs:

public class ApplicationRole : IdentityRole
{
}

ApplicationUser.cs:

  public class ApplicationUser : OpenIddictUser
{
}

ServiceController.cs:

 [Authorize(ActiveAuthenticationSchemes = OAuthValidationDefaults.AuthenticationScheme)]
[Route("api/service")]
public class ServiceController : Controller
{
    private readonly UserManager<ApplicationUser> _userManager;

    public ServiceController(UserManager<ApplicationUser> userManager)
    {
        _userManager = userManager;
    }

    [HttpGet]
    [Route("getdata")] 
    public async Task<IActionResult> GetData()
    {
        var user = await _userManager.GetUserAsync(User);
        if (user == null) return Ok("No user / not logged in");// if Authorize is not applied
        return Ok(user);
    }
}

Ключ здесь - ServiceController.cs: [Authorize(ActiveAuthenticationSchemes = OAuthValidationDefaults.AuthenticationScheme)]

@Pinpoint: я не использовал app.UseOAuthValidation (), потому что он возвращал 302 и перенаправлял в Account / Login.

Так что теперь это работает так:

  • доступ к http://domain.com , пользователь может зарегистрироваться, войти, посмотреть данные и т. д.
  • пользователь может скачать мобильное приложение, зарегистрироваться, войти и получить данные

Реализация регистрации пользователя на стороне API легко и просто.

Проблема заключалась в том, что при использовании fiddler и выдаче GET для http://domain.com/api/service/getdata возвращалось значение 302 и перенаправление на учетную запись / логин. Если я удалю app.UseIdentity (), то if вернет 401 Unauthorized, но пользователь не сможет больше войти в систему с помощью пользовательского интерфейса http://domain.com . Добавление этого [Authorize(ActiveAuthenticationSchemes = OAuthValidationDefaults.AuthenticationScheme)]в мой ServiceController решило проблему.

@Pinpoint, в чем выгода app.UseOAuthValidation ()?

Автор: user2818430 Размещён: 19.07.2016 09:12
Вопросы из категории :
32x32