【发布时间】:2016-02-24 20:31:44
【问题描述】:
背景
我有使用 OWIN + Azure AD 进行身份验证的 Web 表单应用程序。该应用程序托管在 IIS 10.0.10586.0 中。该应用程序作为 www.mydomain.com 托管在根目录(默认网站)。我还有子 .net 应用程序(不是虚拟目录),其中包含一些静态页面和一些 .Net 代码。因此经过身份验证的用户可以访问静态页面 www.mydomain.com/pages/page1.html
我遵循的步骤:
1> 创建 Web 表单应用程序并使用 OWIN 植入 Azure AD 身份验证,如 here 或 here
2> IIS 10 下的托管应用程序作为根应用程序(默认网站)
3> 此时一切正常,用户被重定向到 Microsoft 的登录页面,在那里进行身份验证,然后在成功身份验证后重定向回 mydomain.com
4> 我看到 System.Web.HttpContext.Current.Request.IsAuthenticated 是“真”
5> 我有一些静态页面,我希望只有经过身份验证的用户才能访问。所以我在默认网站下创建了一个新的应用程序,并相应地设置了物理路径。
6> 我还在 web.config 中添加了授权和 runAllManagedModulesForAllRequests(见下文)
7> 当经过身份验证的用户尝试访问页面 www.mydomain.com/pages/page1.html 他得到访问被拒绝错误
(注意如果我创建子虚拟目录它可以工作。但我想要应用程序而不是虚拟目录)
访问被拒绝
错误消息 401.2.:未经授权:登录失败,原因是 服务器配置。验证您是否有权查看此内容 目录或页面基于您提供的凭据和 Web 服务器上启用的身份验证方法。联系网络 服务器管理员寻求更多帮助。
下面是 IIS 和应用程序池的快照(我也尝试将身份设置为 LocalSystem)“页面”是经过身份验证的用户无法访问的子应用程序。
OWIN 启动类
[assembly: OwinStartup(typeof(AzureWithSL.Web.Startup))]
namespace AzureWithSL.Web
{
public partial class Startup
{
private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
private static string tenant = ConfigurationManager.AppSettings["ida:Tenant"];
private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
string authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant);
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
}
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
PostLogoutRedirectUri = postLogoutRedirectUri,
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = context =>
{
context.HandleResponse();
context.Response.Redirect("/Error?message=" + context.Exception.Message);
return Task.FromResult(0);
}
}
});
}
}
}
应用程序启动页面
public class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
SignIn();
}
public void SignIn()
{
// Send an OpenID Connect sign-in request.
if (!System.Web.HttpContext.Current.Request.IsAuthenticated)
{
HttpContext.Current.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = "/" }, OpenIdConnectAuthenticationDefaults.AuthenticationType);
}
}
}
Web.Config
<configuration>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="owin:AutomaticAppStartup" value="true" />
<add key="ida:ClientId" value="someid" />
<add key="ida:Tenant" value="mytenant.onmicrosoft.com" />
<add key="ida:AADInstance" value="https://login.microsoftonline.com/{0}" />
<add key="ida:PostLogoutRedirectUri" value="http://localhost/Default.aspx" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5.1" />
<httpRuntime targetFramework="4.5.1" />
<authorization>
<deny users="?" />
</authorization>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
<location path="Default.aspx">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
</configuration>
EDIT1
因此,无论我在子应用程序中是否有代码或静态页面,经过身份验证的用户都无法访问子应用程序。
我认为这是 OWIN 或 IIS 中的错误,有人可以确认一下吗?
EDIT2
所以在挖掘了几个小时后,我有点接近解决方案。
1> 我正在使用带有 OpenID Connect 的 Azure AD 进行单点登录身份验证。身份验证机制创建 cookie。为了使身份验证 cookie 跨越应用程序边界(即使第二个应用程序是 IIS 中的子应用程序),我们仍然需要使用相同的机器密钥来解密 cookie。在我的情况下,我的第二个应用程序设置为子应用程序(参见上面的 IIS 屏幕截图),所以我只需将机器密钥添加到根应用程序中。 (在旧的 FormsAuthentication 中,我们必须做同样的事情)
2> 最重要的是子应用程序需要是 .Net 4.5 或更高版本,并配置了 OWIN 和身份框架。它不能只是包含一些静态文件的文件夹。它必须是正确的 .Net Web 应用程序(我讨厌这个,因为我有几个子应用程序是使用 .Net 4 开发的 WCF 服务。所以现在我必须将所有这些应用程序转换为 4.5 并配置 OWIN & 身份框架和测试。真的吗???)
使用旧的 FormsAuthentication 我们不必这样做。 Authorization 元素能够保护子应用程序并在用户通过身份验证时允许访问,无论子应用程序是否包含 .net 应用程序、wcf 服务、静态 html 文件或图像。
【问题讨论】:
标签: asp.net iis authorization owin azure-active-directory