2012年7月11日 星期三

網站地圖結合角色動態顯示選單


1. 登入頁認證通過時建立票證並加入cookie
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, Login1.UserName, DateTime.Now, DateTime.Now.AddHours(8), false, [角色名稱(多個則以逗號隔開)]);
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
HttpCookie authCookie = new HttpCookie([cookie名稱], encryptedTicket);
Response.Cookies.Add(authCookie);

2. Global.asax 認證通過後取得cookie 中的票證並建立GenericPrincipal存入Context.User
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
        if (Context.User == null) return;
        if (!Context.User.Identity.IsAuthenticated) return;
     
        string cookieName = [cookie名稱];
        if (!Context.Request.Cookies.AllKeys.Contains(cookieName)) return;
        HttpCookie authCookie = Context.Request.Cookies[cookieName];
        FormsAuthenticationTicket authTicket = null;
        authTicket = FormsAuthentication.Decrypt(authCookie.Value);
        string[] roles = authTicket.UserData.Split(new char[] { ',' });//如果有多個角色以逗號隔開則拆開
        FormsIdentity id = new FormsIdentity(authTicket);
        var principal = new System.Security.Principal.GenericPrincipal(id, roles);
        Context.User = principal;//存到HttpContext.User中
}

3. 網站地圖(web.sitemap)設定各節點可存取角色
<sitemap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0">
<sitemapnode roles="*" title="..."> <= 設定可以看到節點的角色,星號表示全部,若不設定則不會顯示
<sitemapnode description="..." title="..." url="..."> <= 包含網址的節點無法指定角色,會沒有作用
<sitemapnode description="..." title="..." url="...">
</sitemapnode>
</sitemapnode></sitemapnode></sitemap>

4. web.config 設定SiteMapProvider 及特定網頁可存取角色
  <sitemap defaultprovider="XmlSiteMapProvider" enabled="true">
      <providers>
        <add description="SiteMap provider which reads in .sitemap XML files." name="XmlSiteMapProvider" securitytrimmingenabled="true" sitemapfile="Web.sitemap" type="System.Web.XmlSiteMapProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
      </add></providers>
    </sitemap>

說明 : SiteMapProvider 加入 securityTrimmingEnabled="true" 的選項以啟用角色控制節點機制

  <location path="[網址]">
    <system.web>
      <authorization>
        <allow roles="[允許的角色]" />
        <deny users="*" />
      </authorization>
    </system.web>
  </location>

說明 : 針對網址節點若要控制某些角色才能存取則使用 location 來指派角色


5. 於主頁面加入選單控制項並結合SiteMapProvider,在此以 treeview 為例
<asp:TreeView ID="TreeView1" runat="server" DataSourceID="SiteMapDataSource1" ShowLines="True">
< /asp:TreeView>
< asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" SiteMapProvider="XmlSiteMapProvider" />


Entity Framework 建立新物件並儲存後馬上取得關聯資料

使用 CreateProxy 建立物件,不要直接 new var newmodel = _contextXXX.CreateProxy<yyy>(); ... _contextXXX.yyy.Add(newmodel); await _contextXXX.SaveC...