7

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

поток выглядит следующим образом:

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

Как я могу настроить Openiddict OAuth, поэтому я могу защитить API конечных точек с помощью OAuth?

ответ

5

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

Ваш сценарий звучит как хороший кандидат для the simple "resource owner password credentials" grant, который в основном эквивалент OAuth2 базовой или аутентификации форм.

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

Создать новый контроллер AccountController/RegistrationController API ответственного создания новых учетных записей:

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

Настройка 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, чтобы защитить ваши интерфейсы:

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

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

Для получения дополнительной информации, вы также можете читать этот блог, написанный Майком Rousos для .NET веб-разработки Microsoft и инструменты блога: Bearer Token Authentication in ASP.NET Core

1

Хорошо, спасибо @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 является предварительной и простой.

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

@Pinpoint Какое преимущество приложения.UseOAuthValidation()?

+0

Проверьте этот ответ http://stackoverflow.com/questions/41551430/asp-net-core-no-redirect-on-api-auth-error/41551965#41551965, используя app.MapWhen это другой способ, чтобы вам не нужно [Авторизовать (ActiveAuthenticationSchemes = OAuthValidationDefaults.AuthenticationScheme)] –

+0

Мне интересно, можно ли по умолчанию установить «ActiveAuthenticationSchemes = OAuthValidationDefaults.AuthenticationScheme», чтобы я не мог установить его на каждом контроллере. –