【问题标题】:ASP.NET Core 1.0 OAuth Server using Openiddict使用 Openiddict 的 ASP.NET Core 1.0 OAuth 服务器
【发布时间】:2016-11-20 17:14:14
【问题描述】:

我想使用 Openiddict OAuth 来保护我的 ASP.NET Core 1.0 Web 应用程序中的 api 端点。 api 端点将由电话应用程序调用,用户必须使用用户名和密码登录。

流程是这样的:

  • 用户可以通过网络应用程序注册和登录:https://www.domain.com
  • 用户安装手机app,即可使用手机app登录注册。登录、注册和数据访问通过api 端点完成:示例:https://www.domain.com/api/service/getsomedata

如何配置 Openiddict OAuth,以便使用 OAuth 保护 API 端点?

【问题讨论】:

    标签: oauth asp.net-core asp.net-core-mvc asp.net-core-1.0 openiddict


    【解决方案1】:

    如何配置 Openiddict OAuth,以便使用 OAuth 保护 API 端点?

    您的场景听起来很适合 the simple "resource owner password credentials" grant,它基本上相当于基本身份验证或表单身份验证的 OAuth2。

    以下是我的建议:

    创建一个新的AccountController/RegistrationController API 控制器,负责创建新帐户:

    由于此阶段用户帐号不存在,因此此处不能使用令牌认证(就像默认的AccountController.Register模板在用户注册前不能要求cookies认证一样)。

    配置 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.UseMvc() 之前添加app.UseOAuthValidation()。要强制进行身份验证,只需像使用 cookie 身份验证一样使用 [Authorize] 属性。

    不要犹豫与this sample 一起玩。它的客户端部分不使用移动应用程序,但您应该很容易理解它的工作原理。

    有关更多信息,您还可以阅读 Mike Rousos 为 Microsoft .NET Web 开发和工具博客撰写的这篇博文:Bearer Token Authentication in ASP.NET Core

    【讨论】:

      【解决方案2】:

      好的,感谢@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,用户可以注册、登录、查看数据等。
      • 用户可以下载手机APP、注册、登录、获取数据

      在 api 端实现用户注册登录非常简单直接。

      问题是使用 fiddler 并向http://domain.com/api/service/getdata 发出 GET 返回 302 并重定向到帐户/登录。如果我删除 app.UseIdentity(),那么 if 将返回 401 Unauthorized 但用户将无法再使用 UI http://domain.com 登录。将此[Authorize(ActiveAuthenticationSchemes = OAuthValidationDefaults.AuthenticationScheme)] 添加到我的 ServiceController 解决了问题。

      @Pinpoint app.UseOAuthValidation() 有什么好处?

      【讨论】:

      • 查看这个答案stackoverflow.com/questions/41551430/…,使用 app.MapWhen 是另一种方式,这样您就不必 [Authorize(ActiveAuthenticationSchemes = OAuthValidationDefaults.AuthenticationScheme)]
      • 我想知道是否可以将“ActiveAuthenticationSchemes = OAuthValidationDefaults.AuthenticationScheme”设为默认值,这样我就不必在每个控制器上都设置它了。
      猜你喜欢
      • 2017-12-08
      • 2017-09-17
      • 1970-01-01
      • 2015-05-17
      • 2020-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多