我有一个ASP.Net WebAPI 2.1,我刚刚过渡到使用带有令牌令牌的Identity 2.0。这很好用。现在我试图引入一些MVC代码来创建一组登录和用户管理页面。我的问题是,当我将WebApi Request.IsAuthenticated
设置为HttpConfiguration
时,我似乎无法从我的Razor视图中获得SuppressDefaultHostAuthentication
。
以下是我的代码,我的想法是如何让这两种方案都能运行:(
我的Startup.cs
设置了身份OWIN模块和WebAPI:
public class Startup
{
public void Configure(IAppBuilder app)
{
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/account/externalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14)
};
app.UseOAuthBearerTokens(OAuthOptions);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager, DefaultAuthenticationTypes.ApplicationCookie))
}
});
var httpConfiguration = new HttpConfiguration();
// Disable this line to allow Request.IsAuthenticated to work
// But by doing this, it allows the 'redirect' to kick in on unauthenticated API requests, which returns a HTML page for a webapi call, rather than the JSON 'unauthenticated' response
httpConfiguration.SuppressDefaultHostAuthentication();
httpConfiguration.Filters.Add(new HostAuthenticationFilter(DefaultAuthenticationTypes.ApplicationCookie));
httpConfiguration.MapHttpAttributeRoutes();
app.UseWebApi(httpConfiguration);
}
}
这是我的Global.asax.cs
,它设置了MVC方面(AFAIK OWIN不支持任何形式的app.UseMvc()
):
public class WebApiApplication : HttpApplication
{
protected void Application_Start()
{
// pretty much the defaults here for everything, just renamed
AreaRegistration.RegisterAllAreas();
MvcConfig.ConfigureFilters(GlobalFilters.Filters);
MvcConfig.ConfigureRoutes(RouteTable.Routes);
MvcConfig.ConfigureBundles(BundleTable.Bundles);
}
}
现在在我的Razor视图中,我想使用身份示例中使用的Request.IsAuthenticated
,但是在启用httpConfiguration.SuppressDefaultHostAuthentication
时会失败。我理解此扩展的目标是在Identity中间件运行后删除当前标识 - 以便WebAPI身份验证过滤器可以随意执行。但我希望在MVC方面,抑制不会发生。
示例剃刀视图:
@if (Request.IsAuthenticated) // false when using httpConfiguration.SuppressDefaultHostAuthentication
{
<div>User.Identity.Email</div>
}
任何人都可以帮助我吗?这甚至可能吗?
谢谢!
答案 0 :(得分:1)
看起来它与应用构建器的排序有关。如果我在WebAPI之前放置Identity承载配置,那么我的WebAPI请求仍然使用Identity OWIN模块。通过在WebAPI配置之后放置Cookie配置,Cookie身份解析在WebAPI标识删除之后和MVC执行之前发生。
不确定这是否是正确的&#39;这样做的方法,但它似乎解决了我打开的所有测试用例。
public class Startup
{
public void Configure(IAppBuilder app)
{
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/account/externalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14)
};
app.UseOAuthBearerTokens(OAuthOptions);
var httpConfiguration = new HttpConfiguration();
httpConfiguration.SuppressDefaultHostAuthentication();
httpConfiguration.Filters.Add(new HostAuthenticationFilter(DefaultAuthenticationTypes.ApplicationCookie));
httpConfiguration.MapHttpAttributeRoutes();
app.UseWebApi(httpConfiguration);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager, DefaultAuthenticationTypes.ApplicationCookie))
}
});
}
}
修改强>
上述工作,但似乎更好地利用app.MapWhen()
功能来做到这一点。
public class Startup
{
public void Configure(IAppBuilder app)
{
// setup auth for all requests
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/account/externalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14)
};
app.UseOAuthBearerTokens(OAuthOptions);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager, DefaultAuthenticationTypes.ApplicationCookie))
}
});
// setup webapi for only /api requests
app.MapWhen(
context => context.Request.Uri.PathAndQuery.StartsWith("/api"),
newApp => {
var httpConfiguration = new HttpConfiguration();
httpConfiguration.SuppressDefaultHostAuthentication();
httpConfiguration.Filters.Add(new HostAuthenticationFilter(DefaultAuthenticationTypes.ApplicationCookie));
httpConfiguration.MapHttpAttributeRoutes();
app.UseWebApi(httpConfiguration);
}
}
}