通过 ASP.NET Identity 和 Autofac OWIN 集成进行授权

2024-03-27

(在这个问题的底部添加了更新)

我有一个 Web 应用程序,它使用 MVC5 和 WebAPI2 以及 Autofac for DI。该应用程序使用 ASP.NET Identity 和 oAuth 不记名令牌,尽管后者可能不是重点。这一切都运行得很好,但此时我需要在整个 OWIN 管道以及应用程序的其余部分共享注入服务的相同实例,因此我正在尝试为 MVC 和 Web 设置 Autofac 的 OWIN 集成API。我似乎很接近 - 一切似乎都有效,除了AuthorizeAttibutes on ApiControllers。 oAuth 过程成功完成,我最终使用不记名令牌登录,但随后尝试在 WebAPI 控制器/操作上使用所述令牌进行授权失败。

具体来说,在IsAuthorized的方法System.Web.Http.AuthorizeAttribute, IPrincipal.Identity似乎它没有被正确实例化,因为它没有适当的声明和IsAuthenticated属性总是假的。 Autofac 的开发者表示此属性应与 OWIN 集成一起使用 https://github.com/autofac/Autofac/issues/509,即使该代码使用GlobalConfiguration 这对于 OWIN 集成来说是不可取的 http://docs.autofac.org/en/latest/integration/webapi.html#owin-integration。我看到了多个删除建议config.SuppressDefaultHostAuthentication() (here https://stackoverflow.com/questions/23785528/user-iprincipal-not-avaliable-on-apicontrollers-constructor-using-web-api-2-1 and here https://stackoverflow.com/questions/27294032/webapi-owin-identity-is-not-authorized-after-signing-in),虽然不建议这样做,但我出于绝望而尝试过,但没有成功——对于我的特定配置,这会导致 IPrincipal 返回为空。我也尝试过修改一个更简单的示例项目 https://github.com/AkosLukacs/Autofac-OWIN-MVC比我自己用的AuthorizeAttribute在 WebAPI 控制器上,也没有成功。此时我已经没有什么可尝试的了,非常感谢您的帮助。

这是我的 Startup.cs:

[assembly: OwinStartup(typeof (Startup))]
namespace Project.Web
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            var builder = new ContainerBuilder();
            builder.RegisterControllers(Assembly.GetExecutingAssembly());
            var config = new HttpConfiguration();
            builder.RegisterHttpRequestMessage(config);
            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
            RegisterGeneralTypes(builder);
            var container = builder.Build();
            WebApiConfig.Register(config);
            config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
            WebApiFilterConfig.RegisterGlobalFilters(config.Filters);

            app.UseAutofacMiddleware(container);
            app.UseAutofacWebApi(config);
            app.UseAutofacMvc();
            app.UseWebApi(config);

            ConfigureAuth(app);
        }

        private static void RegisterGeneralTypes(ContainerBuilder builder)
        {
            builder.Register(c => new DomainModelContext())
                .AsSelf()
                .InstancePerRequest();

            builder.Register(c => HttpContext.Current.User.Identity)
                .As(typeof (IIdentity));

            builder.RegisterType<EmailService>()
                .AsImplementedInterfaces()
                .InstancePerRequest();

            builder.Register(c => new IdentityFactoryOptions<DomainUserManager>
            {
                DataProtectionProvider = DataProtectionProvider
            }).InstancePerRequest();

            builder.RegisterType<DomainUserManager>()
                .AsSelf()
                .UsingConstructor(typeof (IIdentityMessageService),
                    typeof (IdentityFactoryOptions<DomainUserManager>),
                    typeof (CustomUserStore))
                .InstancePerRequest();

            builder.RegisterType<CustomUserStore>()
                .AsImplementedInterfaces()
                .AsSelf()
                .InstancePerRequest();

            builder.Register(c => HttpContext.Current.GetOwinContext().Authentication)
                .As<IAuthenticationManager>();
        }
    }
}

和我的 Startup.Auth.cs:

public partial class Startup
{
    internal static IDataProtectionProvider DataProtectionProvider;
    public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
    public static string PublicClientId { get; private set; }

    public void ConfigureAuth(IAppBuilder app)
    {
        var onValidateIdentity = SecurityStampValidator
            .OnValidateIdentity<DomainUserManager, DomainUser, int>(
                validateInterval: TimeSpan.FromMinutes(30),
                regenerateIdentityCallback: (manager, user) =>
                    user.GenerateUserIdentityAsync(manager, CookieAuthenticationDefaults.AuthenticationType),
                getUserIdCallback: id => id.GetUserId<int>());

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            LoginPath = new PathString("/account/login"),

            Provider = new CookieAuthenticationProvider
            {
                OnValidateIdentity = onValidateIdentity
            }
        });
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        // Configure the application for OAuth based flow
        PublicClientId = "self";
        OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/token"),
            Provider = new ApplicationOAuthProvider(PublicClientId),
            AuthorizeEndpointPath = new PathString("/api/v1/account/externallogin"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
        };

        // Enable the application to use bearer tokens to authenticate users
        app.UseOAuthBearerTokens(OAuthOptions);

        DataProtectionProvider = app.GetDataProtectionProvider();
    }
}

我认为这涵盖了它,但我很乐意根据要求发布额外的代码。

UPDATE

所以基于朱穆罗的回答 https://stackoverflow.com/questions/37826551/authorization-with-asp-net-identity-autofac-owin-integration/37839448#37839448,我按照建议更改了注册顺序。然而,这只是将完全相同的问题从 Web API 授权转移到 MVC 授权。由于我在更新之前就已经使用了 MVC 身份验证,因此我最终尝试在管道中注册身份验证两次,如下所示:

app.UseAutofacMiddleware(container);
ConfigureAuth(app);
app.UseAutofacWebApi(config);
app.UseAutofacMvc();
app.UseWebApi(config);
ConfigureAuth(app);

这是可行的,但我真的不能说我理解为什么,而且我无法想象这样做两次是好的。所以现在我有新的问题:

  1. WebAPI 需要在 中注册 Auth,这是有道理的 首先是管道,但为什么 MVC 要我注册 授权last?
  2. 我怎样才能清理这个并避免打电话ConfigureAuth twice?

您必须以正确的顺序将中间件添加到应用程序管道中。在 MVC 和 Web Api 中间件处理请求之前,必须验证承载令牌。

在您的中尝试此顺序Configuration() method:

public void Configuration(IAppBuilder app)
{
    ...
    app.UseAutofacMiddleware(container);
    ConfigureAuth(app);
    app.UseAutofacMvc();
    app.UseWebApi(config);
    app.UseAutofacWebApi(config);
    ...
}

我希望它有帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过 ASP.NET Identity 和 Autofac OWIN 集成进行授权 的相关文章

  • 仅为一个通用命令处理程序注册 Autofac 装饰器

    我们有很多通用命令处理程序 它们由 Autofac 以开放通用方式注册 我们有几个装饰器来装饰所有的手柄 现在我需要仅为一个命令处理程序注册一个装饰器 而不影响所有其他命令处理程序 这是我的尝试 但我似乎没有正确注册 这是与我们的代码类似的
  • 如何以编程方式访问 AspXGridView 的 EditItemTemplate 内的任何 AspxControl

    这很简单 我觉得自己像个白痴 我最近开始使用 DevX Controls 它的文档和示例项目很糟糕 我的问题是 我的 aspx 页面上有一个 ASPxGridView
  • 在 MVC 中使用 Request.URL 和 Request.URLReferrer 获取当前链接的替代方案?

    我希望在我的中编写一个方法 属性BaseController允许任何操作获取当前 URL 的类 如果我打电话localhost Keyword Edit 1我可以用Request Url获取网址 但是 如果我的编辑视图中有部分视图 我需要使
  • 回调和部分回发有什么区别?

    有区别吗 或者这些术语是同义词吗 抱歉 如果之前有人问过这个问题 我只能找到a之间的区别full回发和回调 我已经知道完整回发有何不同 在使用 ASP Net 2 0 时 如果这很重要的话 顺便问一下 这重要吗 或者这些术语对于任何基于 W
  • 从 MVC 控制器返回 JSON 字符串

    我使用以下代码将对象发送 接收到我的 mvc 控制器 ajax url createOrUpdateTimeRecord data JSON stringify data type POST dataType json contentTyp
  • 在这种情况下设置 EnableEventValidation="false" 是否存在安全风险?

    我有一个包含用户控件的页面 当用户单击图像按钮将其带到另一个显示他们单击的表行项目的详细信息的页面时 会发生错误 System ArgumentException Invalid postback or callback argument
  • C# 中的密码恢复工具不起作用

    嗨 我对此还很陌生 我创建了一个门户 用户可以登录并在其中查看我制作的其他程序 问题是密码恢复似乎不起作用 我没有收到任何错误消息 我只是收到消息 我们无法访问您的信息 请重试 我已经正确设置了 ASP NET 配置 并使用不同的用户和权限
  • 验证码怎么写?

    我正在开发一个注册表 我想放置验证码 我生成一个随机字符串 但如何将其转换为图像 否则我如何开发验证码或任何参考 谢谢 Try out 验证码 http recaptcha net plugins aspnet 或查看博客文章 使用 Asp
  • 如何在 ASP.NET 5/vNext/Core 中使用 Elmah?

    我对如何在 ASP NET 5 MVC 6 项目中使用 Elmah 有点困惑 我从 nuget 得到了包 它添加了 Elmah Mvc 2 1 2 到project json 中的依赖项 我不知道从这里到哪里去 以前 nuget 会向 we
  • 如何在 MVC 5 中设置自定义 ClaimsPrincipal?

    我创建了一个自定义主体类 public class FacebookPrincipal ClaimsPrincipal public JObject Data get set 我想用它 当用户登录时 我尝试设置 var fbP new Fa
  • 随机无效视图状态错误

    我知道关于这个主题有很多问题 我已经阅读了所有这些问题 我正在使用 IIS8 Net 4 5 用户随机收到无效视图状态错误 我无法弄清楚 一旦发生这种情况 他们返回网站的唯一方法就是清除浏览器缓存 在我的 web config 中我有
  • WebAPI 请求格式的异常

    在项目中使用RC版本的MVC4 WebAPI 我在API服务器端不断遇到以下错误 System FormatException The format of value application json charset utf 8 is in
  • mvc3,你能给控制器一个显示名称吗?

    我用的是mvc3 是否可以为控制器和操作指定显示名称 DisplayName Facebook Employee public class EmployeeController Controller 在我的面包屑中 我将获得控制器名称和操作
  • MvcHttpHandler 似乎没有实现 IHttpHandler

    我正在尝试为 MVC 控制器执行自定义 ActionResult 在我正在查看的示例中 它显示了下面的代码片段 我的 System Web Mvc MvcHttpHandle 没有实现 IHttpHandler 接口 System Web
  • MVC Owin Identity 2 CheckPasswordAsync() 将不会执行

    我有两个问题似乎彼此相关 并且 stackoverflow 中的其他重复项都不能回答我的问题 First当 的时候PasswordSignInAsync方法执行它永远不会停止或抛出任何异常它只是继续执行 var result await S
  • .net MVC 将 MP4 流式传输到 iDevice 问题

    我一直在编写用于提供视频服务的一段代码 但遇到了一些问题 代码如下 public ResumingFileStreamResult GetMP4Video string videoID if User Identity IsAuthenti
  • PHP 和 ASP.Net 可以在 IIS 7.5 中的同一网站中一起运行吗?

    我们网站的一部分是用 PHP 完成的 而我们网站的一部分是用 ASP Net 完成的 我们刚刚使用 Windows Server 2008 R2 设置了一个新的 Web 服务器 其中安装了 IIS 7 5 我知道 IIS 7 支持 PHP
  • dropdownlist DataTextField 由属性组成?

    有没有一种方法可以通过 C 使 asp net 中的下拉列表的 datatextfield 属性由对象的多个属性组成 public class MyObject public int Id get set public string Nam
  • 使用 GUID 作为 ASP.NET MVC 数据库中的 ID

    我正在学习 ASP NET MVC 我正在关注有关的基本教程之一asp net http www asp net mvc whatisaspmvc 由于我并不总是严格遵循教程 因此我决定使用 GUID 作为标识列而不是整数 一切都工作正常
  • “if”在 ASP.NET MVC View (.aspx) 文件中被认为有害?

    我记得看到一个博客 或其他内容 说你不应该在 ASP NET MVC 的 aspx 文件中使用 但我不记得它说的替代方案是什么 有人记得看过这个并指出我吗 基本上 这意味着您的视图中不应该有大量的 if 语句 您的控制器和视图模型应该能够处

随机推荐

  • Android 5-5.1 (API 21-22) 上的 WebView 崩溃 Resources$NotFoundException: 字符串资源 ID #0x2040002

    我正在将 Android 应用程序从 API 27 更新到 API 29 我注意到在尝试在基于 5 0 和 或 5 1 的模拟器上渲染 WebView 时发生崩溃 在运行 6 0 或更高版本 API 23 29 的模拟器上不会发生此问题 我
  • 如何实现和维护多个actionListener

    好的 我有一个类 我们称之为 MenuBarClass 其中包含多个 Menu 和 MenuItem 我想为每个 MenuItem 分配一个动作侦听器 但是 而不是执行以下操作 menuitem 1 addActionListener ne
  • 包内初始化订单

    我有文件 main a go b go c go a go package main import fmt func init fmt Println a func main b go package main import fmt fun
  • 如何在mininet中将不同的交换机连接到不同的遥控器?

    我想将 mininet 虚拟网络的不同交换机连接到不同的远程控制器 但不知道如何继续 请提供任何方法来做到这一点 任何 python 示例都值得赞赏 我推荐你阅读此邮件形式为 mininet 的邮件列表档案 https mailman st
  • 单实例登录实现

    我在我的项目 在 ASP NET 2 0 中构建的 Web 应用程序 中遇到了一个严重的问题 如下所述 假设我已经给出了用户 ID singh nirajan 并且用户说 User1 使用该用户 ID 登录到系统 现在我的要求是每当其他用户
  • javascript 将 int 转换为 float

    我有一个变量 var fval 4 现在我想输出为 4 00 JavaScript 只有一个Number存储浮点值的类型 没有 int Edit 如果要将数字格式化为小数点后两位数字的字符串 请使用 4 toFixed 2
  • 如何使用 Jackson 将字符串反序列化为自定义对象?

    我有一个想要解析的 JSON name john 我必须使用以下层次结构 这些类是不可变的 我必须通过静态工厂方法访问它们 这是必要的 因此建议对其中任何一个进行修改都是没有意义的Name or Person class Name stat
  • 如何添加 CSS3 过渡并显示 HTML5 详细信息/摘要标签?

    仅使用CSS3 有没有一种方法可以在页面上添加漂亮的淡入和从左滑动过渡效果DETAILS SUMMARY reveal 有关此新标签的演示 请参阅此演示 details transition height 3s ease in
  • c3p0如何关闭所有数据库连接并在需要时重新打开它们?

    我有一个 TimerTask 每天运行一次 大约 1 或 2 小时 每次运行时 它都会创建数百个线程来为 MySQL 数据库中的每个表执行一些计算工作 我使用c3p0作为数据库源连接池 每个线程在计算前获取连接 计算后关闭连接 我设置连接池
  • iOS 8 - 视频和声音文件无法从主屏幕 Web 应用程序播放

    我有一个 HTML5 Web 应用程序 它使用 JWPlayer 来嵌入视频和播客 这在 iOS 7 中运行良好 无论是在 Safari 中还是作为 Web 应用程序保存到主屏幕时 在 iOS 8 中 视频和声音文件也可以在 Safari
  • 使用 sed 为选项卡添加背景颜色?

    是否可以使用 sed 更改选项卡 或任何其他文本 的背景颜色 以便 例如 我可以运行如下所示的内容 somefunction sed e s some pattern set bg color 1 unset bg color g Yes
  • QNetworkAccessManager和HTTP持久连接

    HTTP 1 1 默认支持持久连接 因此我想使用发出第一个 HTTP 请求时设置的相同连接来发送第二个 http 请求 如何通过Qt来实现这一点 如果我只是在第一个请求完成后发出第二个请求 如下所示 manager gt get QNetw
  • 当维度在类实例化时未定义时,如何将浮点数组声明为 Objective-C 中的类变量?

    在 Java 中 它看起来像这样 class Foo float array Foo instance new Foo instance array new float 10 你可以只使用一个指针 float array Allocate
  • 列出Innodb全文索引的单词

    在 Mysql Innodb 中 我创建了一个全文索引 是否有一个查询可以用来检索全文索引中包含的所有单词的列表 我的想法是使用一个文本字段来保存标签列表的 json 转储 我可以使用全文查询来检索与标签匹配的行 它有效 剩下的问题是检索索
  • ctypes 结构中的默认值

    在 ctypes 结构中 是否可以指定默认值 例如 使用常规 python 函数 您可以执行以下操作 def func a b 2 print a b 这将允许这种行为 func 1 prints 3 func 1 20 prints 21
  • 从传统的基于 XUL 的附加组件中访问附加 SDK?

    我有一个大型且复杂的基于 XUL 的插件 我需要使用插件 SDK 中的一些函数 这可能吗 如果是这样 是否有人有工作示例代码 最好使用 page worker 模块 以下是 devtools 的做法 但某些模块会阻塞 明显的候选者是self
  • 无法访问viewBinding

    我现在正在 Kotlin 中使用 viewBinding here is my build gradle 启用 ViewBinding 并具有自动导入 ViewBinding 依赖项 but Android Studio still sho
  • 如何更好地组织数据库以适应用户状态的变化

    我关注的用户可以是 未确认 或 已确认 后者意味着他们获得完全访问权限 而前者意味着他们正在等待主持人的批准 我不确定如何设计数据库来解释这种结构 我的一个想法是拥有两个不同的表 confirmedUser 和 unconfirmedUse
  • 获取parent.location.url - iframe - 从子级到父级

    我得到了一个在 iframe 中显示的页面 我需要从该页面 子页面 获取带有js的parent location url 两个站点位于不同的域中 我想 警报 父 位置 url 但我收到这个错误 权限被拒绝http 父域 http paren
  • 通过 ASP.NET Identity 和 Autofac OWIN 集成进行授权

    在这个问题的底部添加了更新 我有一个 Web 应用程序 它使用 MVC5 和 WebAPI2 以及 Autofac for DI 该应用程序使用 ASP NET Identity 和 oAuth 不记名令牌 尽管后者可能不是重点 这一切都运