![](/img/trans.png)
[英]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.