ASP.NET 4.5 或替代框架中的 OpenIdDict?
Posted
技术标签:
【中文标题】ASP.NET 4.5 或替代框架中的 OpenIdDict?【英文标题】:OpenIdDict in ASP.NET 4.5 or alternative frameworks? 【发布时间】:2019-01-10 08:22:19 【问题描述】:在一个旧项目中,我们使用了 ASP.NET 4.5,我想在其中使用框架 OpenIdDict。它是由 ASP.NET Core 1 和 2 制作的。我还能使用它吗?我需要注意什么?如果我不能使用它,你知道哪些替代方案?
OpenIdDict 链接:https://github.com/openiddict/openiddict-core
【问题讨论】:
试试 OpenIddict 在后台使用的ASOS。 【参考方案1】:编辑:OpenIddict 3.0 现在与 OWIN/Katana 原生兼容,并且可以在任何 >= ASP.NET 4.6.1 应用程序中使用,而无需使用任何适配器。阅读这两篇博文了解更多信息:
Introducing OpenIddict 3.0 beta1 Adding OpenIddict 3.0 to an OWIN application从技术上讲,通过使用 Microsoft.AspNetCore.Owin
适配器包和一些调整,可以在 ASP.NET 4.x 应用程序中使用为 ASP.NET Core 1.x/2.x 设计的中间件。
这是一个 OWIN 自托管控制台应用程序的原型(它与使用 OWIN SystemWeb
主机的 ASP.NET 4.x 应用程序非常相似):
Program.cs:
using System;
using Microsoft.Owin.Hosting;
namespace OpenIddictOwinDemo
public static class Program
public static void Main(string[] args)
const string address = "http://localhost:12556/";
using (WebApp.Start<Startup>(address))
Console.WriteLine($"Server is running on address, press CTRL+C to stop.");
Console.ReadLine();
Startup.cs:
using System;
using System.Diagnostics;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Owin;
namespace OpenIddictOwinDemo
public class Startup
public void Configuration(IAppBuilder app)
app.UseBuilder(ConfigureServices(), Configure);
IServiceProvider ConfigureServices()
var services = new ServiceCollection();
// In a real ASP.NET Core application, these services are
// registered by the hosting stack. Since this application
// is actually an OWIN app, they must be registered manually.
var listener = new DiagnosticListener("Microsoft.AspNetCore");
services.AddSingleton<DiagnosticListener>(listener);
services.AddSingleton<DiagnosticSource>(listener);
services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
services.AddDbContext<DbContext>(options =>
options.UseInMemoryDatabase("db");
);
services.AddOpenIddict()
.AddCore(options =>
options.UseEntityFrameworkCore()
.UseDbContext<DbContext>();
)
.AddServer(options =>
options.AcceptAnonymousClients();
options.AllowPasswordFlow();
options.EnableTokenEndpoint("/connect/token");
options.DisableHttpsRequirement();
options.UseCustomTokenEndpoint();
);
return services.BuildServiceProvider(validateScopes: true);
void Configure(IApplicationBuilder app)
// This inline middleware is required to be able to use scoped services.
// In a real ASP.NET Core application, this is done for you by a special
// middleware automatically injected by the default hosting components.
app.Use(next => async context =>
var provider = context.RequestServices;
using (var scope = provider.CreateScope())
try
context.RequestServices = scope.ServiceProvider;
await next(context);
finally
context.RequestServices = provider;
);
app.UseDeveloperExceptionPage();
app.UseAuthentication();
KatanaExtensions.cs:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.FileProviders;
using Owin;
namespace OpenIddictOwinDemo
using AddMiddleware = Action<Func<
Func<IDictionary<string, object>, Task>,
Func<IDictionary<string, object>, Task>
>>;
using AppFunc = Func<IDictionary<string, object>, Task>;
public static class KatanaExtensions
public static IAppBuilder UseBuilder(this IAppBuilder app,
IServiceProvider provider, Action<IApplicationBuilder> configuration)
if (app == null)
throw new ArgumentNullException(nameof(app));
if (provider == null)
throw new ArgumentNullException(nameof(provider));
if (configuration == null)
throw new ArgumentNullException(nameof(configuration));
AddMiddleware add = middleware =>
app.Use(new Func<AppFunc, AppFunc>(next => middleware(next)));
;
add.UseBuilder(configuration, provider);
return app;
public class HostingEnvironment : IHostingEnvironment
public string EnvironmentName get; set;
public string ApplicationName get; set;
public string WebRootPath get; set;
public IFileProvider WebRootFileProvider get; set;
public string ContentRootPath get; set;
public IFileProvider ContentRootFileProvider get; set;
OpenIddictExtensions:
using System;
using System.Security.Claims;
using System.Threading.Tasks;
using AspNet.Security.OpenIdConnect.Extensions;
using AspNet.Security.OpenIdConnect.Primitives;
using Microsoft.Extensions.DependencyInjection;
using OpenIddict.Server;
namespace OpenIddictOwinDemo
public static class CustomOpenIddictServerExtensions
public static OpenIddictServerBuilder UseCustomTokenEndpoint(
this OpenIddictServerBuilder builder)
if (builder == null)
throw new ArgumentNullException(nameof(builder));
return builder.AddEventHandler<OpenIddictServerEvents.HandleTokenRequest>(
notification =>
var request = notification.Context.Request;
if (!request.IsPasswordGrantType())
return Task.CompletedTask;
// Validate the user credentials.
// Note: to mitigate brute force attacks, you SHOULD strongly consider
// applying a key derivation function like PBKDF2 to slow down
// the password validation process. You SHOULD also consider
// using a time-constant comparer to prevent timing attacks.
if (request.Username != "alice@wonderland.com" ||
request.Password != "P@ssw0rd")
notification.Context.Reject(
error: OpenIdConnectConstants.Errors.InvalidGrant,
description: "The specified credentials are invalid.");
return Task.CompletedTask;
// Create a new ClaimsIdentity holding the user identity.
var identity = new ClaimsIdentity(
notification.Context.Scheme.Name,
OpenIdConnectConstants.Claims.Name,
OpenIdConnectConstants.Claims.Role);
// Add a "sub" claim containing the user identifier, and attach
// the "access_token" destination to allow OpenIddict to store it
// in the access token, so it can be retrieved from your controllers.
identity.AddClaim(OpenIdConnectConstants.Claims.Subject,
"71346D62-9BA5-4B6D-9ECA-755574D628D8",
OpenIdConnectConstants.Destinations.AccessToken);
identity.AddClaim(OpenIdConnectConstants.Claims.Name, "Alice",
OpenIdConnectConstants.Destinations.AccessToken);
// ... add other claims, if necessary.
var principal = new ClaimsPrincipal(identity);
notification.Context.Validate(principal);
return Task.CompletedTask;
);
实际上,我不推荐它,因为它有点老套(Microsoft.AspNetCore.Owin
适配器多年未更新)。相反,您可能希望采用微服务架构并将基于 OpenIddict 的授权服务器移至单独的 ASP.NET Core 服务。
【讨论】:
以上是关于ASP.NET 4.5 或替代框架中的 OpenIdDict?的主要内容,如果未能解决你的问题,请参考以下文章
.NET Core(或 ASP.NET 5)中是不是有 MEF 的替代品
asp.net中的ADO.NET实体框架适用于不同的数据库及其性能
如何在 asp.net 4.5 中使用 facebook 帐户开发登录