[英]Asp.Net Web Api Token Based Authorization WITHOUT OWIN and AspNet.Identity
[英]Authorization with ASP.NET Identity & Autofac OWIN integration
(此问题的底部添加了更新)
我有一个Web应用程序,它使用MVC5和WebAPI2以及用于DI的Autofac。 该应用程序使用ASP.NET身份和oAuth承载令牌,虽然后者可能不重要。 这一切都运行得很好,但此时我需要在整个OWIN管道以及我的应用程序的其余部分共享我注入的服务的相同实例,因此我正在尝试为MVC和Web设置Autofac的OWIN集成API。 我似乎很接近 - 除了ApiControllers
AuthorizeAttibutes
之外,一切似乎都ApiControllers
。 oAuth进程成功完成,我最终使用不记名令牌登录,但随后尝试使用WebAPI控制器/操作上的所述令牌进行授权失败。
具体来说,在System.Web.Http.AuthorizeAttribute
的IsAuthorized
方法中, IPrincipal.Identity
似乎没有正确实例化,因为它没有相应的声明,并且IsAuthenticated
属性始终为false。 Autofac的开发人员表示该属性应该与OWIN集成一起使用 ,即使该代码使用的GlobalConfiguration
不适用于OWIN集成 。 我已经看到了删除config.SuppressDefaultHostAuthentication()
( 这里和这里 )的多个建议,虽然这是不可取的,但我已经尝试了绝望但是没有用 - 对于我的特定配置,这会导致IPrincipal返回null 。 我还尝试修改一个比我自己更简单的示例项目 ,以便在WebAPI控制器上使用AuthorizeAttribute
,但也没有成功。 在这一点上,我没有尝试的东西,非常感谢帮助。
这是我的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
所以根据jumuro的回答 ,我按照建议更改了我的注册顺序。 但是,这只是将完全相同的问题从Web API授权转移到MVC授权。 由于我在更新之前有MVC auth工作,我最终尝试在管道中注册两次auth,如下所示:
app.UseAutofacMiddleware(container);
ConfigureAuth(app);
app.UseAutofacWebApi(config);
app.UseAutofacMvc();
app.UseWebApi(config);
ConfigureAuth(app);
这是有效的,但我真的不能说我理解为什么,我无法想象这样做两次是好的。 所以现在我有了新的问题:
ConfigureAuth
? 您必须以正确的顺序将中间件添加到应用程序管道。 在MVC和Web Api中间件处理请求之前,必须验证承载令牌。
在Configuration()
方法中尝试此顺序:
public void Configuration(IAppBuilder app)
{
...
app.UseAutofacMiddleware(container);
ConfigureAuth(app);
app.UseAutofacMvc();
app.UseWebApi(config);
app.UseAutofacWebApi(config);
...
}
我希望它有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.