2011-02-03 13 views
3

MVC初心者の質問:私のプロジェクトは&です。今私は特定のビューへのアクセスを制限し始めます。 VS 2010パッケージには標準のビルトインセキュリティモジュールが付属しています。これには、あなたのユーザー名とパスワードを保存する小さな縮約データベースが含まれています。あなたは非標準的なアプローチを使用します。ASP.NET MVCセキュリティのクイックスタート

まあ、私は組み込みのセキュリティを使用したくないです。私は自分のユーザーテーブルを持っています。パスワードを自分自身で暗号化する方法を知っています。ありがとう、ありがとう。私がやってみたいのは、ログイン方法です。ログインが成功したと判断した場合は、セッションを認証済みとして設定し、ユーザーが制限付きビューにアクセスできるようにします。あまりにも難しくはありませんか?

私はGoogle MVCセキュリティのためにgoogledしました。問題は情報の欠如ではなくむしろあまりにも多くの人が私の個人的なOutOfMemoryExceptionを切って私に "クイックスタート"を与えることができれば、本当に感謝しています。

答えて

4

ASP.NETの優れた点の1つは、非常に拡張性が高いことです。はい、認証と承認の既定のモデルは、ASP.NET提供のメンバーシップテーブルを(個別のデータベースに格納するか、独自に追加する)使用することです。幸いにも、その周りに道があります。

あなたが探しているものを達成する最も簡単な方法は、既存のデータベースを使用するカスタムMembershipProviderを作成することです。私はあなたをお勧めしたい

MSDN - Implementing a Membership Provider

+0

Ok ...私はカスタムメンバーシッププロバイダを構築しました...今、私はそれをどうしますか? –

+0

@Shaul - デフォルトの代わりにカスタムメンバーシッププロバイダを使用するようにweb.configを変更します。 –

+0

よろしくお願いします。今、メンバーシッププロバイダに、そのユーザーが認証されたことを知らせるにはどうすればよいですか? –

1

このコードを参考にして、独自のモデルとデータベースを使用してpoepleをログインしたりログアウトしたりしてください。 IdentitySessionクラスは、サインインされたユーザーデータを取得するためにコントローラで使用できます。私はコードを少し簡略化しようとしましたが、ここでいくつかのコードをカットしていますので、ただ実行するとは思わないでください。それが役に立てば幸い。

public ActionResult Login(int pageId) { 
    ViewData["ReturnUrl"] = Request["ReturnUrl"]; 
    return View(Cms3Configuration.DefaultViewModelWithPage(attachedPage)); 
} 

public ActionResult Process(int pageId, string login, string password, string ReturnUrl) { 
    var user = userRepository.GetByUserName(login); 
    ViewData["ReturnUrl"] = ReturnUrl; 
    if (user != null && authenticator.VerifyAccount(user, password)) { 
    authenticator.SignIn(user); 
    if (ReturnUrl.IsNotEmpty()) { 
     return Redirect(ReturnUrl); 
    } 
    return Redirect("~" + attachedPage.Parent.Url); 
    } 
    ////login failed 
    TempData[TempDataKeys.Error] = "Invalid login"; 
    return RedirectToAction("Login", new { pageId = pageId, ReturnUrl }); 
} 

public ActionResult Logout(int pageId) { 
    authenticator.SignOut(); 
    return RedirectToAction<LoginController>(x => x.Login(pageId), new {pageId = pageId}); 
} 

public interface IAuthenticator { 
    void SignIn(User person); 
    IIdentity GetActiveIdentity(); 
    WindowsPrincipal GetActiveUser(); 
    void SignOut(); 
    bool VerifyAccount(User person, string password); 
    bool HasRole(string person, string role); 
} 

public class Authenticator : IAuthenticator { 
    private readonly IHttpContextProvider _httpContextProvider; 
    private readonly ICryptographer _cryptographer; 
    private readonly IRepository repository; 

    public Authenticator(IHttpContextProvider httpContextProvider, ICryptographer cryptographer, IRepository repository) { 
    _cryptographer = cryptographer; 
    this.repository = repository; 
    _httpContextProvider = httpContextProvider; 
    } 

    public void SignIn(User user) { 
    FormsAuthentication.SignOut(); 
    if (user == null) 
     return; 
    DateTime issued = DateTime.Now; 
    DateTime expires = issued.AddMinutes(30); 
    if (user.ExpiryDate.HasValue) { 
     if (user.Expires && expires > user.ExpiryDate) 
     expires = (DateTime) user.ExpiryDate; 
    } 
    var roles = user.Roles.Select(x => x.Name).ToList(); 
    var ticket = new FormsAuthenticationTicket(1, user.UserName, issued, expires, false, string.Join(",", roles.Distinct().ToArray())); 
    var encryptedTicket = FormsAuthentication.Encrypt(ticket); 
    var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket) { Expires = ticket.Expiration }; 
    _httpContextProvider.GetCurrentHttpContext().Response.Cookies.Add(authCookie); 
    } 

    public IIdentity GetActiveIdentity() { 
    var httpcontext = _httpContextProvider.GetCurrentHttpContext(); 
    if (httpcontext == null || httpcontext.User == null) 
     return null; 
    return httpcontext.User.Identity; 
    } 

    public WindowsPrincipal GetActiveUser() { 
    return _httpContextProvider.GetCurrentHttpContext().User as WindowsPrincipal; 
    } 

    public void SignOut() { 
    FormsAuthentication.SignOut(); 
    } 

    public bool VerifyAccount(User person, string password) { 
    string passwordHash = _cryptographer.HashPassword(password, person.PasswordSalt); 
    return passwordHash == person.Password && !person.HasExpired() && person.Approved == true; 
    } 

} 

public interface IIdentitySession<T> { 
    T GetLoggedInIdentity(); 
    bool IsAuthenticated { get; } 
    bool IsAdministrator { get; } 
} 

public class IdentitySession<T> : IIdentitySession<T> where T : Identity { 
    private readonly IAuthenticator<T> authenticator; 
    private readonly IRepository repository; 
    private readonly IHttpContextProvider httpContextProvider; 
    private T currentIdentity; 
    private static readonly object _lock = new object(); 

    public IdentitySession(IAuthenticator<T> authenticator, IRepository repository, 
         IHttpContextProvider httpContextProvider) { 
    this.authenticator = authenticator; 
    this.activeDirectoryMapper = activeDirectoryMapper; 
    this.repository = repository; 
    this.httpContextProvider = httpContextProvider; 
    } 

    public virtual T GetLoggedInIdentity() { 
    IIdentity identity = authenticator.GetActiveIdentity(); 

    if (identity == null) 
     return null; 

    if (!identity.IsAuthenticated) 
     return null; 

    lock (_lock) { 
     if (currentIdentity == null) { 
     currentIdentity = repository.Query<T>().Where(x => x.UserName == identity.Name).FirstOrDefault(); 
     } 
    } 

    return currentIdentity; 
    } 

    public bool IsAuthenticated { 
    get { return httpContextProvider.GetCurrentHttpContext().User.Identity.IsAuthenticated; } 
    } 

    public bool IsAdministrator { 
    get { return false; } 
    } 
} 
+0

OhとIdentitySessionは、Unityリゾルバを使用してRequest Lifetimeを持つように設定されています。 – Richard

1

:そうすることで、あなたはまだあなたのコントローラ内の属性を経由して、あなたのアクションへのアクセスを制御することができることを意味し、既存のASP.NET MVCの認証フレームワークにカスタム認証ロジックをプラグインすることができますFormsAuthenticationServiceを使用して、一度満足しているユーザーに署名する必要があります。

ボイラープレートMVC3インターネットアプリケーションプロジェクトテンプレートは、これにいくつかの指針を与えます(メンバーシップコードをメンバーシップコードに置き換えてください)。

コードへのアクセスを制限したい場合は、CodeAccessSecurity属性とPermission属性を使用できます。これらはクラスレベルとメソッドレベルで適用できます。たとえば

[System.Security.Permissions.PrincipalPermission(SecurityAction.Demand, Authenticated = true, Role = "Admin")] 
public ActionResult Index() 
{ 
.... 
} 

もちろん、web.configファイルを使用してWebサイトの領域にアクセス権を設定することができます。

関連する問題