更新された回答:
元の回答Combining Forms Authentication and Basic Authentication を投稿してから数か月後に、この質問に出くわしました。その船は出航したので、私はこのソリューションをテストしていませんが、有望に見えます。
元の回答:
私の知る限り、この質問に対する答えは「いいえ」です。Umbraco コンテンツ ページのヘッダーを変更することはできないため、特定の LDAP サーバーに対して自身を認証するようにブラウザーに指示することはできません。
ただし、フォーム認証を使用して同じように動作させることができました (Active Directory に対して認証し、データベースに対して承認します)。以下に、この認証を Umbraco で機能させるために必要なすべてのコードを含めました。
ログインページ
ログインページは、Umbraco View に次の Partial View と Surface Control を追加したものです。@Html.Action("MemberUmbLogin", "MemberUmbLoginSurface")
@model CustomUmbraco.Models.MemberUmbLoginModel
@if (User.Identity.IsAuthenticated)
{
<p>Logged in: @User.Identity.Name</p>
<p>@Html.ActionLink("Log out", "MemberUmbLogout", "MemberUmbLoginSurface")</p>
}
else
{
using (Html.BeginUmbracoForm("MemberUmbLogin", "MemberUmbLoginSurface"))
{
@Html.EditorFor(x => Model)
<input type="submit" />
}
<p>@TempData["Status"]</p>
}
ログインモデル
public class MemberUmbLoginModel
{
public string Username { get; set; }
[DataType(DataType.Password)]
public string Password { get; set; }
public bool RememberMe { get; set; }
}
サーフェス コントローラー
public class MemberUmbLoginSurfaceController : SurfaceController
{
//
// GET: /MemberUmbLogin/
[HttpGet]
[ActionName("MemberUmbLogin")]
public ActionResult MemberUmbLoginGet()
{
return PartialView("MemberUmbLogin", new MemberUmbLoginModel());
}
[HttpGet]
public ActionResult MemberUmbLogout()
{
Session.Clear();
FormsAuthentication.SignOut();
return Redirect("/");
}
[HttpPost]
[ActionName("MemberUmbLogin")]
public ActionResult MemberUmbLoginPost(MemberUmbLoginModel model)
{
string returnUrl = GetValidReturnUrl(Request.UrlReferrer);
if (Membership.ValidateUser(model.Username, model.Password))
{
FormsAuthentication.SetAuthCookie(model.Username, model.RememberMe);
if (Url.IsLocalUrl(returnUrl) && !String.IsNullOrWhiteSpace(returnUrl))
{
return Redirect(returnUrl);
}
return RedirectToCurrentUmbracoPage();
}
TempData["Status"] = "Invalid username or password";
return RedirectToCurrentUmbracoPage();
}
private static String GetValidReturnUrl(Uri uri)
{
string returnUrl = null;
if (uri != null && !String.IsNullOrWhiteSpace(uri.PathAndQuery) && uri.PathAndQuery.StartsWith("/") &&
!uri.PathAndQuery.StartsWith("//") && !uri.PathAndQuery.StartsWith("/\\"))
{
returnUrl = uri.PathAndQuery;
}
return returnUrl;
}
}
標準の Umbraco Role Provider でカスタム MembershipProvider を使用しています。メンバーがログインするたびに、Umbraco 以外のデータベースに基づいてメンバーの役割を更新するために、MembershipProvider に依存しています。次に、MembershipProvider は適切なグループでメンバーを更新します。
注: Umbraco のロール プロバイダーを使用しているため、Umbraco 以外のデータベースのロールを「メンバー グループ」として Umbraco に追加する必要があります。
Web.config
<!-- Membership Provider -->
<membership defaultProvider="CustomMembershipProvider" userIsOnlineTimeWindow="15">
<providers>
<clear />
<add name="CustomMembershipProvider" type="CustomUmbraco.MembershipProviders.CustomMembershipProvider" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="4" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" defaultMemberTypeAlias="NetIDAlias" passwordFormat="Hashed" />
<add name="UmbracoMembershipProvider" type="Umbraco.Web.Security.Providers.MembersMembershipProvider, Umbraco" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="4" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" defaultMemberTypeAlias="Member" passwordFormat="Hashed" />
<add name="UsersMembershipProvider" type="Umbraco.Web.Security.Providers.UsersMembershipProvider, Umbraco" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="4" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" passwordFormat="Hashed" />
</providers>
</membership>
<!-- Role Provider -->
<roleManager enabled="true" defaultProvider="UmbracoRoleProvider">
<providers>
<clear />
<add name="UmbracoRoleProvider" type="Umbraco.Web.Security.Providers.MembersRoleProvider" />
</providers>
</roleManager>
メンバーシッププロバイダー
public class CustomMembershipProvider : MembershipProvider
{
private String GetDomainFreeName(String fullName)
{
return fullName.Contains("\\") ? fullName.Substring(fullName.IndexOf("\\") + 1) : fullName;
}
public override bool ValidateUser(string username, string password)
{
DirectoryEntry directoryEntry = new DirectoryEntry(ConfigurationManager.ConnectionStrings["LDAPConnection"].ConnectionString, username, password);
DirectorySearcher searcher = new DirectorySearcher(directoryEntry);
String domainFreeName = GetDomainFreeName(username);
searcher.Filter = String.Format("(&(objectClass=user)(SAMAccountName={0})(!msExchUserAccountControl=2))", domainFreeName);
SearchResult result;
try
{
result = searcher.FindOne();
}
catch (COMException)
{
return false; // authentication failed
}
if (result != null)
{
NotReallyARoleProvider provider = new NotReallyARoleProvider();
provider.UpdateUserRoles(domainFreeName);
Member m = Member.GetMemberFromLoginName(domainFreeName);
Member.AddMemberToCache(m);
return true;
}
return false;
}
}
UpdateUserRoles メソッド
public void UpdateUserRoles(String username)
{
var groups = this.GetRolesForUser(username); // this is the method that gets the roles for your user.
this.RemoveUsersFromRoles(new[] { username }, this.GetAllRoles());
this.AddUsersToRoles(new[] { username }, groups);
}
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
{
foreach (String username in usernames)
{
Member m = Member.GetMemberFromLoginName(username);
if (m == null)
{
m = Member.MakeNew(username, MemberType.GetByAlias("Member"), new User(0));
m.LoginName = username;
}
roleNames.ForEach(group => m.AddGroup(MemberGroup.GetByName(group).Id));
m.Save(true);
}
}
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
{
foreach (String username in usernames)
{
Member m = Member.GetMemberFromLoginName(username);
if (m == null)
{
m = Member.MakeNew(username, MemberType.GetByAlias("Member"), new User(0));
m.LoginName = username;
}
roleNames.ForEach(group => m.RemoveGroup(MemberGroup.GetByName(group).Id));
m.Save(true);
}
}
最後に、ActiveDirectoryMembershipProvider を使用しない理由は、アカウントを変更するための十分な権限を取得できなかったためです。
この解決策は完璧にはほど遠いですが、私にとってはうまくいきます。ページにログインしても正しいグループに属していないように動作するという問題が発生した場合、または Umbraco インターフェースからメンバーを削除しても を呼び出したときにメンバーが引き続き表示される場合はMember.GetMemberFromLoginName(username)
、次の可能性があります。プロバイダーのメンバー保存コードを次の行に一度置き換えます。
ApplicationContext.Current.Services.MemberService.DeleteMembersOfType(MemberType.GetByAlias("Member").Id);
これにより、ethereal リポジトリに格納されているすべてのメンバーが消去されます。
このすべてのコードを配置すると、ユーザーは通常どおり、Umbraco バックオフィスのコンテンツ ページにアクセスしたいグループを選択できます。