在混合的 MVC / WebForms Web 应用程序中配置授权
Configuring Authorization in a mixed MVC / WebForms Web app
我目前正在将 WebForms/MVP 应用程序的一些组件迁移到 MVC 中。到目前为止,除了授权外,一切正常。无论如何,当我导航到登录页面的 MVC 版本时,我被重定向到在 Web.config
:
中设置的 aspx 页面
<authentication mode="Forms">
<forms name=".MyWebSite" enableCrossAppRedirects="true" loginUrl="Login.aspx" timeout="60" path="/" defaultUrl="~/Pages/Landing.aspx"></forms>
</authentication>
我试过使用 AllowAnonymous
,但似乎 Webforms 配置优先。这是我的登录控制器:
[RouteArea("User", AreaPrefix = "")]
public class AuthenticationController : Controller {
[Route("Login")]
[AllowAnonymous]
public ActionResult Login() {
return View();
}
}
我的目录结构如下所示:
> Web Project
> Areas
> User
> Controllers
> AuthController
> Views
> Login.cshtml
在我的 web.config 中,我看到以下内容允许匿名访问错误页面:
<location path="Error">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
然而,为 Areas
路径复制它是行不通的(可能是因为 cshtml 文件实际上并不像 aspx 页面那样位于那里?)。
现在,如果我登录(通过登录的 aspx 版本)并且我的用户已通过身份验证,我就可以很好地访问 MVC 实现。路由和渲染工作得很好。它只是允许未经身份验证的用户访问 MVC 页面(无需重定向到 aspx 实现),这似乎是一个挑战。我究竟做错了什么?
编辑
我发现的一个非常 hacky 的部分解决方案(基于 Turning off ASP.Net WebForms authentication for one sub-directory)如下:
protected void Application_BeginRequest(object sender, EventArgs e) {
// lots of existing web.config controls for which webforms folders can be accessed
// read the config and skip checks for pages that authorise anon users by having
// <allow users="?" /> as the top rule.
//
// check local config
var localAuthSection = ConfigurationManager.GetSection("system.web/authorization") as AuthorizationSection;
// this assumes that the first rule will be <allow users="?" />
var localRule = localAuthSection.Rules[0];
if (localRule.Action == AuthorizationRuleAction.Allow && localRule.Users.Contains("?")) {
// then skip the rest
return;
}
// get the web.config and check locations
var conf = WebConfigurationManager.OpenWebConfiguration("~");
foreach (ConfigurationLocation loc in conf.Locations) {
// find whether we're in a location with overridden config
// get page name
var currentPath = Path.GetFileName(this.Request.Path);
if (currentPath.Equals(loc.Path, StringComparison.OrdinalIgnoreCase)) {
// get the location's config
var locConf = loc.OpenConfiguration();
var authSection = locConf.GetSection("system.web/authorization") as AuthorizationSection;
if (authSection != null) {
// this assumes that the first rule will be <allow users="?" />
var rule = authSection.Rules[0];
if (rule.Action == AuthorizationRuleAction.Allow && rule.Users.Contains("?")) {
// then skip the rest
return;
}
}
}
}
}
这意味着我可以这样指定 "Login":
<location path="Login">
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
</location>
但是所有关联的 CSS/JS 都不会呈现,除非我仔细检查并为这些文件类型添加规则。 got 可以更优雅地解决这个问题。
我找到了我认为的正确解决方案。在我的 web.config 中,我将 loginUrl
设置为我的 MVC 页面:
<authentication mode="Forms">
<forms name=".MyWebSite" enableCrossAppRedirects="true" loginUrl="Login" timeout="60" path="/" defaultUrl="~/Pages/Landing.aspx"></forms>
</authentication>
然后我必须在我的 authController 中设置 cookie,这样当我重定向到 aspx 页面时,HttpContext.CurrentUser
被定义为登录用户:
FormsAuthentication.SetAuthCookie(model.Username, true);
我不知道这是否确实是解决此问题的正确方法,但到目前为止它似乎有效。如果有人有任何反馈,我会保持开放状态。
在问题中,您混合了两部分 1. 身份验证和 2. 授权。
- 身份验证:表单身份验证即可。
- 对于授权:您必须在应用程序的 MVC 部分中实现自定义授权过滤器。参考:http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute(v=vs.118).aspx
它还可以用作 ASP.NET 表单的自定义属性。
看看微软的教程"mvc music store"。第 7 部分是关于身份验证和授权的配置。阅读 5-10 页,您现在有了一个基本概念。
我目前正在将 WebForms/MVP 应用程序的一些组件迁移到 MVC 中。到目前为止,除了授权外,一切正常。无论如何,当我导航到登录页面的 MVC 版本时,我被重定向到在 Web.config
:
<authentication mode="Forms">
<forms name=".MyWebSite" enableCrossAppRedirects="true" loginUrl="Login.aspx" timeout="60" path="/" defaultUrl="~/Pages/Landing.aspx"></forms>
</authentication>
我试过使用 AllowAnonymous
,但似乎 Webforms 配置优先。这是我的登录控制器:
[RouteArea("User", AreaPrefix = "")]
public class AuthenticationController : Controller {
[Route("Login")]
[AllowAnonymous]
public ActionResult Login() {
return View();
}
}
我的目录结构如下所示:
> Web Project
> Areas
> User
> Controllers
> AuthController
> Views
> Login.cshtml
在我的 web.config 中,我看到以下内容允许匿名访问错误页面:
<location path="Error">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
然而,为 Areas
路径复制它是行不通的(可能是因为 cshtml 文件实际上并不像 aspx 页面那样位于那里?)。
现在,如果我登录(通过登录的 aspx 版本)并且我的用户已通过身份验证,我就可以很好地访问 MVC 实现。路由和渲染工作得很好。它只是允许未经身份验证的用户访问 MVC 页面(无需重定向到 aspx 实现),这似乎是一个挑战。我究竟做错了什么?
编辑 我发现的一个非常 hacky 的部分解决方案(基于 Turning off ASP.Net WebForms authentication for one sub-directory)如下:
protected void Application_BeginRequest(object sender, EventArgs e) {
// lots of existing web.config controls for which webforms folders can be accessed
// read the config and skip checks for pages that authorise anon users by having
// <allow users="?" /> as the top rule.
//
// check local config
var localAuthSection = ConfigurationManager.GetSection("system.web/authorization") as AuthorizationSection;
// this assumes that the first rule will be <allow users="?" />
var localRule = localAuthSection.Rules[0];
if (localRule.Action == AuthorizationRuleAction.Allow && localRule.Users.Contains("?")) {
// then skip the rest
return;
}
// get the web.config and check locations
var conf = WebConfigurationManager.OpenWebConfiguration("~");
foreach (ConfigurationLocation loc in conf.Locations) {
// find whether we're in a location with overridden config
// get page name
var currentPath = Path.GetFileName(this.Request.Path);
if (currentPath.Equals(loc.Path, StringComparison.OrdinalIgnoreCase)) {
// get the location's config
var locConf = loc.OpenConfiguration();
var authSection = locConf.GetSection("system.web/authorization") as AuthorizationSection;
if (authSection != null) {
// this assumes that the first rule will be <allow users="?" />
var rule = authSection.Rules[0];
if (rule.Action == AuthorizationRuleAction.Allow && rule.Users.Contains("?")) {
// then skip the rest
return;
}
}
}
}
}
这意味着我可以这样指定 "Login":
<location path="Login">
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
</location>
但是所有关联的 CSS/JS 都不会呈现,除非我仔细检查并为这些文件类型添加规则。 got 可以更优雅地解决这个问题。
我找到了我认为的正确解决方案。在我的 web.config 中,我将 loginUrl
设置为我的 MVC 页面:
<authentication mode="Forms">
<forms name=".MyWebSite" enableCrossAppRedirects="true" loginUrl="Login" timeout="60" path="/" defaultUrl="~/Pages/Landing.aspx"></forms>
</authentication>
然后我必须在我的 authController 中设置 cookie,这样当我重定向到 aspx 页面时,HttpContext.CurrentUser
被定义为登录用户:
FormsAuthentication.SetAuthCookie(model.Username, true);
我不知道这是否确实是解决此问题的正确方法,但到目前为止它似乎有效。如果有人有任何反馈,我会保持开放状态。
在问题中,您混合了两部分 1. 身份验证和 2. 授权。
- 身份验证:表单身份验证即可。
- 对于授权:您必须在应用程序的 MVC 部分中实现自定义授权过滤器。参考:http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute(v=vs.118).aspx 它还可以用作 ASP.NET 表单的自定义属性。
看看微软的教程"mvc music store"。第 7 部分是关于身份验证和授权的配置。阅读 5-10 页,您现在有了一个基本概念。