OWIN:IIS在访问子应用程序

时间:2016-02-24 20:31:44

标签: asp.net iis authorization owin azure-active-directory

背景
我有使用OWIN + Azure AD进行身份验证的Web表单应用程序。该应用程序托管在IIS 10.0.10586.0中。该应用程序在root(默认网站)上托管为www.mydomain.com。我还有子.net应用程序(不是虚拟目录),它包含一些静态页面和一些.Net代码。经过身份验证的用户可以访问静态页面,如www.mydomain.com/pages/page1.html

我遵循的步骤:
1 GT;使用OWIN创建Web表单应用程序并植入Azure AD身份验证,如 here here
2 - ; IIS 10下的托管应用程序作为根应用程序(默认网站)
3 GT;此时一切正常,User被重定向到Microsoft的登录页面,在那里进行身份验证,然后成功进行身份验证后重定向回mydomain.com
4>我看到System.Web.HttpContext.Current.Request.IsAuthenticated是“true”
5个我有一些静态页面,我只希望经过身份验证的用户可以访问。所以我在默认网站下创建了一个新的应用程序,并相应地设置了物理路径 6个我还添加了授权和web.config中的runAllManagedModulesForAllRequests(见下文)
7个当经过身份验证的用户尝试访问页面www.mydomain.com/pages/page1.html时,他会获得访问被拒绝错误

注意,如果我创建子虚拟目录,它可以工作。但我希望有应用程序而不是虚拟目录)

  

访问被拒绝
  错误消息401.2。:未经授权:由于登录失败   服务器配置。确认您有权查看此内容   目录或页面基于您提供的凭据和   Web服务器上启用的身份验证方法。联系网站   服务器的管理员以获得更多帮助。

以下是IIS& amp;的快照应用程序池(我也尝试过设置身份到LocalSystem)" pages"是经过身份验证的用户无法访问的子应用程序。

enter image description here

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&GT;我使用Azure AD与OpenID Connect进行单点登录身份验证。身份验证机制创建cookie。为了使身份验证cookie跨越应用程序边界(即使第二个应用程序是IIS中的子应用程序),我们仍然需要使用相同的机器密钥来解密cookie。在我的情况下,我的第二个应用程序设置为子应用程序(请参阅上面的IIS屏幕截图)所以我只需要将机器密钥添加到根应用程序中。 (在旧的FormsAuthentication中我们必须做同样的事情)

2 - ;最重要的是子应用程序需要.Net 4.5或后者配置OWIN和身份框架。它不能只是带有一些静态文件的文件夹。它需要是正确的.Net Web应用程序 (我讨厌这个,因为我有几个子应用程序是使用.Net 4开发的WCF服务。所以现在我必须将所有这些应用程序转换为4.5并配置OWIN &amp;身份框架和测试。真的???)
使用旧的FormsAuthentication,我们不必这样做。 Authorization元素能够保护子应用程序并允许在用户进行身份验证时进行访问,无论子应用程序是否包含.net应用程序,wcf服务,静态html文件或图像。

1 个答案:

答案 0 :(得分:0)

所以上面的EDIT2是我的答案
您必须在主应用程序的web.config中使用Machine Key。 (所有子应用程序都将继承它)

所有子应用程序必须配置为OWIN(与主应用程序相同。它们必须匹配clientid,tenant等)