代码之家  ›  专栏  ›  技术社区  ›  dafna

在ASP.NET 4.5或其他框架中使用OpenIdDict?

  •  4
  • dafna  · 技术社区  · 6 年前

    在一个旧项目中,我们使用了ASP.NET 4.5,我想在其中使用OpenIdDict框架。它是vor ASP.NET核心1和2。我还能用吗?我需要注意什么?如果我不能用,你知道哪种选择?

    指向OpenIdDict的链接: https://github.com/openiddict/openiddict-core

    1 回复  |  直到 6 年前
        1
  •  3
  •   Kévin Chalet    6 年前

    从技术上讲,通过使用 Microsoft.AspNetCore.Owin 适配器包和一些调整。

    这是OWIN自托管控制台应用程序的原型(它与使用OWIN的ASP.NET 4.x应用程序非常相似 SystemWeb 主持人):

    程序代码:

    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();
                }
            }
        }
    }
    

    启动.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();
            }
        }
    }
    

    Katanextensions.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核心服务。

    推荐文章