Kei*_*ith 16 asp.net authentication web-config http http-status-code-401
我有一个包含WebForms和MVC页面的大型企业应用程序.它具有我不想更改的现有身份验证和授权设置.
WebForms身份验证在web.config中配置:
<authentication mode="Forms">
<forms blah... blah... blah />
</authentication>
<authorization>
<deny users="?" />
</authorization>
Run Code Online (Sandbox Code Playgroud)
到目前为止相当标准.我有一个REST服务,它是这个大型应用程序的一部分,我想使用HTTP身份验证代替这一项服务.
因此,当用户尝试从REST服务获取JSON数据时,它会返回HTTP 401状态和WWW-Authenticate标头.如果他们以正确形成的HTTP Authorization响应进行响应,则允许他们进入.
问题是,WebForms的覆盖这个处于较低的水平 - 如果返回401(未授权)它将覆盖与302(重定向到登录页面).这在浏览器中很好,但对REST服务没用.
我想关闭web.config中的身份验证设置,覆盖'rest'文件夹:
<location path="rest">
<system.web>
<authentication mode="None" />
<authorization><allow users="?" /></authorization>
</system.web>
</location>
Run Code Online (Sandbox Code Playgroud)
该授权位工作正常,但认证线(<authentication mode="None" />)导致异常:
在应用程序级别之外使用注册为allowDefinition ='MachineToApplication'的部分是错误的.
我在应用程序级别配置它 - 它位于根web.config中 - 并且该错误适用于子目录中的web.configs.
如何覆盖身份验证,以便该站点的所有其余部分都使用WebForms身份验证,而这个目录不使用任何身份验证?
这类似于另一个问题:与ASP.NET MVC JSON请求401响应代码,但我不是在寻找相同的解决方案-我不想只是删除WebForms的认证和全球范围内添加新的自定义代码,还有远涉及很多风险和工作.我想只更改配置中的一个目录.
更新
我想设置一个Web应用程序,并希望所有WebForms页面和MVC视图都使用WebForms身份验证.我希望一个目录使用基本的HTTP身份验证.
请注意,我说的是身份验证,而不是授权.我希望REST调用带有HTTP头中的用户名和密码,我希望WebForm和MVC页面附带来自.Net的身份验证cookie - 在任何一种情况下,都会对我们的数据库进行授权.
我不想重写WebForms身份验证并滚动我自己的cookie - 这似乎是将HTTP授权的REST服务添加到应用程序的唯一方法,这似乎很荒谬.
我无法添加其他应用程序或虚拟目录 - 它必须作为一个应用程序.
如果"rest"只是你根目录中的一个文件夹,那么你几乎就在那里:删除认证线即
<location path="rest">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
Run Code Online (Sandbox Code Playgroud)
或者,您可以将web.config添加到您的rest文件夹中,然后执行以下操作:
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
Run Code Online (Sandbox Code Playgroud)
检查一下.
我已经用混乱的方式解决了这个问题 - 通过欺骗所有现有页面的 global.asax 中的表单身份验证。
我仍然没有完全发挥作用,但它是这样的:
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
if (this.Request.Path.StartsWith(loc.Path, StringComparison.OrdinalIgnoreCase) ||
this.Request.Path.TrimStart('/').StartsWith(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;
}
}
}
}
var cookie = this.Request.Cookies[FormsAuthentication.FormsCookieName];
if (cookie == null ||
string.IsNullOrEmpty(cookie.Value))
{
// no or blank cookie
FormsAuthentication.RedirectToLoginPage();
}
// decrypt the
var ticket = FormsAuthentication.Decrypt(cookie.Value);
if (ticket == null ||
ticket.Expired)
{
// invalid cookie
FormsAuthentication.RedirectToLoginPage();
}
// renew ticket if needed
var newTicket = ticket;
if (FormsAuthentication.SlidingExpiration)
{
newTicket = FormsAuthentication.RenewTicketIfOld(ticket);
}
// set the user so that .IsAuthenticated becomes true
// then the existing checks for user should work
HttpContext.Current.User = new GenericPrincipal(new FormsIdentity(newTicket), newTicket.UserData.Split(','));
}
Run Code Online (Sandbox Code Playgroud)
我对此并不是很满意——这似乎是一次可怕的黑客攻击和重新发明轮子,但看起来这是我的表单验证页面和 HTTP 验证 REST 服务工作的唯一方法同一个应用程序。
| 归档时间: |
|
| 查看次数: |
28037 次 |
| 最近记录: |