[英]ASP.NET Core 1.0 OAuth Server using Openiddict
我想使用Openiddict OAuth来保护我的ASP.NET Core 1.0 Web应用程序中的api端点。 api
端点将由电话应用程序调用,用户必须使用用户名和密码登录。
流程如下:
https://www.domain.com
: https://www.domain.com
api
端点完成的:示例: https://www.domain.com/api/service/getsomedata
: https://www.domain.com/api/service/getsomedata
如何配置Openiddict OAuth,以便使用OAuth保护API端点?
如何配置Openiddict OAuth,以便使用OAuth保护API端点?
您的方案听起来像是简单的“资源所有者密码凭据”授权的良好候选者 ,它基本上是OAuth2等效的基本或表单身份验证。
这是我建议的:
创建一个新的AccountController
/ RegistrationController
API控制器,负责创建新帐户:
由于此阶段不存在用户帐户,因此您无法在此处使用令牌身份验证(就像默认的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验证中间件来保护您的API:
要启用令牌身份验证,请参阅AspNet.Security.OAuth.Validation
1.0.0-alpha2-final包并在app.UseOAuthValidation()
之前添加app.UseMvc()
。 要使身份验证成为必需,只需使用[Authorize]
属性,就像使用Cookie身份验证一样。
不要犹豫,玩这个样本 。 它不会将移动应用程序用于客户端部分,但您应该很容易理解它是如何工作的。
有关更多信息,您还可以阅读此博客文章,由Mike Rousos撰写,用于Microsoft .NET Web开发和工具博客: ASP.NET核心中的承载令牌身份验证
好的,谢谢@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。
所以现在它的工作原理如下:
在api端实现用户注册登录非常简单直接。
问题是使用fiddler并向http://domain.com/api/service/getdata发出GET,返回302并重定向到Account / Login。 如果我删除了app.UseIdentity(),那么如果将返回401 Unauthorized但是用户将无法再使用用户界面http://domain.com登录。 将[Authorize(ActiveAuthenticationSchemes = OAuthValidationDefaults.AuthenticationScheme)]
到我的ServiceController解决了这个问题。
@Pinpoint app.UseOAuthValidation()的好处是什么?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.