gpt4 book ai didi

asp.net - 使用 ASP.NET Identity 和 Autofac OWIN 集成进行授权

转载 作者:行者123 更新时间:2023-12-04 14:56:19 30 4
gpt4 key购买 nike

(已在此问题的底部添加了更新)

我有一个将 MVC5 和 WebAPI2 与 Autofac 用于 DI 的 Web 应用程序。该应用程序使用 ASP.NET 身份和 oAuth 持有者 token ,尽管后者可能不是重点。这一切都运行良好,但此时我需要在整个 OWIN 管道以及我的应用程序的其余部分共享我注入(inject)的服务的相同实例,因此我正在尝试为 MVC 和 Web 设置 Autofac 的 OWIN 集成API。我似乎很接近——除了 AuthorizeAttibutes 之外,一切似乎都正常。在 ApiControllers . oAuth 过程成功完成,我最终使用不记名 token 登录,但随后尝试在 WebAPI Controller /操作上使用所述 token 进行授权失败。

具体来说,在 IsAuthorized System.Web.Http.AuthorizeAttribute的方法, IPrincipal.Identity似乎它没有被正确实例化,因为它没有适当的声明和 IsAuthenticated属性总是假的。 Autofac 的开发人员表示 this attribute should work with the OWIN integrations ,即使该代码使用 GlobalConfiguration which is not advisable for the OWIN integrations .我看到了多个删除 config.SuppressDefaultHostAuthentication() 的建议( herehere ),虽然这不是可取的,但我出于绝望而尝试过但无济于事 - 对于我的特定配置,这会导致 IPrincipal 返回为空。我也试过修改a much simpler example project比我自己用AuthorizeAttribute在 WebAPI Controller 上,也没有成功。在这一点上,我没有东西可以尝试,我们将不胜感激。

这是我的 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();
}
}

我认为这涵盖了它,但我很乐意应要求发布其他代码。

更新

所以基于 jumuro's answer ,我按照建议更改了注册顺序。但是,这只是将完全相同的问题从 Web API 授权转移到 MVC 授权。由于我在更新之前有 MVC 身份验证工作,因此我最终尝试在管道中注册身份验证两次,如下所示:
app.UseAutofacMiddleware(container);
ConfigureAuth(app);
app.UseAutofacWebApi(config);
app.UseAutofacMvc();
app.UseWebApi(config);
ConfigureAuth(app);

这行得通,但我真的不能说我理解为什么而且我无法想象这样做两次是件好事。所以现在我有新的问题:
  • WebAPI 需要在
    管道优先,但为什么 MVC 要我注册
    最后验证?
  • 我怎样才能清理它并避免调用 ConfigureAuth两次?
  • 最佳答案

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

    在您的 Configuration() 中尝试此订单方法:

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

    我希望它有所帮助。

    关于asp.net - 使用 ASP.NET Identity 和 Autofac OWIN 集成进行授权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37826551/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com