2014-01-24 67 views
2

我開始對MVC 5教程和實施角色和用戶爲後面的鏈接:如何只允許用戶在目錄編輯細節

http://typecastexception.com/post/2013/11/11/Extending-Identity-Accounts-and-Implementing-Role-Based-Authentication-in-ASPNET-MVC-5.aspx

通過基於角色的身份驗證的地方,我現在有一個可以創建用戶的管理員以及目錄控制器中列出的公司目錄。只有當用戶使用由管理員設置的用戶名和密碼登錄時,該用戶纔會被重定向到他們所代表的公司頁面以進行編輯,而不是編輯其他人公司的自由控制。

我應該怎麼做呢?

這是我的AccountController:

[Authorize] 
public class AccountController : Controller 
{ 
    public AccountController() 
     : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()))) 
    { 
    } 


    public AccountController(UserManager<ApplicationUser> userManager) 
    { 
     UserManager = userManager; 
    } 


    public UserManager<ApplicationUser> UserManager { get; private set; } 


    [AllowAnonymous] 
    public ActionResult Login(string returnUrl) 
    { 
     ViewBag.ReturnUrl = returnUrl; 
     return View(); 
    } 


    [HttpPost] 
    [AllowAnonymous] 
    [ValidateAntiForgeryToken] 
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) 
    { 
     if (ModelState.IsValid) 
     { 
      var user = await UserManager.FindAsync(model.UserName, model.Password); 
      if (user != null) 
      { 
       await SignInAsync(user, model.RememberMe); 

      } 

      //if (User.Identity.AuthenticationType == "CanEdit") 
      //{ 
      // return RedirectToAction() 
      //} 
      else 
      { 
       ModelState.AddModelError("", "Invalid username or password."); 
      } 
     } 

     // If we got this far, something failed, redisplay form 
     return View(model); 
    } 


    [Authorize(Roles = "Admin")] 
    public ActionResult Register() 
    { 
     return View(); 
    } 


    [HttpPost] 
    [Authorize(Roles = "Admin")] 
    [ValidateAntiForgeryToken] 
    public async Task<ActionResult> Register(RegisterViewModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      var user = model.GetUser(); 
      var result = await UserManager.CreateAsync(user, model.Password); 
      if (result.Succeeded) 
      { 
       return RedirectToAction("Index", "Account"); 
      } 

     } 

     // If we got this far, something failed, redisplay form 
     return View(model); 
    } 


    [Authorize(Roles = "Admin")] 
    public ActionResult Manage(ManageMessageId? message) 
    { 
     ViewBag.StatusMessage = 
      message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed." 
      : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set." 
      : message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed." 
      : message == ManageMessageId.Error ? "An error has occurred." 
      : ""; 
     ViewBag.HasLocalPassword = HasPassword(); 
     ViewBag.ReturnUrl = Url.Action("Manage"); 
     return View(); 
    } 


    [HttpPost] 
    [ValidateAntiForgeryToken] 
    [Authorize(Roles = "Admin")] 
    public async Task<ActionResult> Manage(ManageUserViewModel model) 
    { 
     bool hasPassword = HasPassword(); 
     ViewBag.HasLocalPassword = hasPassword; 
     ViewBag.ReturnUrl = Url.Action("Manage"); 
     if (hasPassword) 
     { 
      if (ModelState.IsValid) 
      { 
       IdentityResult result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword); 
       if (result.Succeeded) 
       { 
        return RedirectToAction("Manage", new { Message = ManageMessageId.ChangePasswordSuccess }); 
       } 
       else 
       { 
        AddErrors(result); 
       } 
      } 
     } 
     else 
     { 
      // User does not have a password so remove any validation errors caused by a missing OldPassword field 
      ModelState state = ModelState["OldPassword"]; 
      if (state != null) 
      { 
       state.Errors.Clear(); 
      } 

      if (ModelState.IsValid) 
      { 
       IdentityResult result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword); 
       if (result.Succeeded) 
       { 
        return RedirectToAction("Manage", new { Message = ManageMessageId.SetPasswordSuccess }); 
       } 
       else 
       { 
        AddErrors(result); 
       } 
      } 
     } 

     // If we got this far, something failed, redisplay form 
     return View(model); 
    } 

    [HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult LogOff() 
    { 
     AuthenticationManager.SignOut(); 
     return RedirectToAction("Index", "Home"); 
    } 


    protected override void Dispose(bool disposing) 
    { 
     if (disposing && UserManager != null) 
     { 
      UserManager.Dispose(); 
      UserManager = null; 
     } 
     base.Dispose(disposing); 
    } 


    [Authorize(Roles = "Admin")] 
    public ActionResult Index() 
    { 
     var Db = new ApplicationDbContext(); 
     var users = Db.Users; 
     var model = new List<EditUserViewModel>(); 
     foreach (var user in users) 
     { 
      var u = new EditUserViewModel(user); 
      model.Add(u); 
     } 
     return View(model); 
    } 


    [Authorize(Roles = "Admin")] 
    public ActionResult Edit(string id, ManageMessageId? Message = null) 
    { 
     var Db = new ApplicationDbContext(); 
     var user = Db.Users.First(u => u.UserName ==id); 
     var model = new EditUserViewModel(user); 
     ViewBag.MessageId = Message; 
     return View(model); 
    } 


    [HttpPost] 
    [Authorize(Roles = "Admin")] 
    [ValidateAntiForgeryToken] 
    public async Task<ActionResult> Edit(EditUserViewModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      var Db = new ApplicationDbContext(); 
      var user = Db.Users.First(u => u.UserName == model.UserName); 
      user.FirstName = model.FirstName; 
      user.LastName = model.LastName; 
      user.Email = model.Email; 
      Db.Entry(user).State = System.Data.Entity.EntityState.Modified; 
      await Db.SaveChangesAsync(); 
      return RedirectToAction("Index"); 
     } 

     // If we got this far, something failed, redisplay form 
     return View(model); 
    } 

    [Authorize(Roles = "Admin")] 
    public ActionResult Delete(string id = null) 
    { 
     var Db = new ApplicationDbContext(); 
     var user = Db.Users.First(u => u.UserName == id); 
     var model = new EditUserViewModel(user); 
     if (user == null) 
     { 
      return HttpNotFound(); 
     } 
     return View(model); 
    } 


    [HttpPost, ActionName("Delete")] 
    [ValidateAntiForgeryToken] 
    [Authorize(Roles = "Admin")] 
    public ActionResult DeleteConfirmed(string id) 
    { 
     var Db = new ApplicationDbContext(); 
     var user = Db.Users.First(u => u.UserName == id); 
     Db.Users.Remove(user); 
     Db.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 


    [Authorize(Roles = "Admin")] 
    public ActionResult UserRoles(string id) 
    { 
     var Db = new ApplicationDbContext(); 
     var user = Db.Users.First(u => u.UserName == id); 
     var model = new SelectUserRolesViewModel(user); 
     return View(model); 
    } 


    [HttpPost] 
    [Authorize(Roles = "Admin")] 
    [ValidateAntiForgeryToken] 
    public ActionResult UserRoles(SelectUserRolesViewModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      var idManager = new IdentityManager(); 
      var Db = new ApplicationDbContext(); 
      var user = Db.Users.First(u => u.UserName == model.UserName); 
      idManager.ClearUserRoles(user.Id); 
      foreach (var role in model.Roles) 
      { 
       if (role.Selected) 
       { 
        idManager.AddUserToRole(user.Id, role.RoleName); 
       } 
      } 
      return RedirectToAction("index"); 
     } 
     return View(); 
    } 


    #region Helpers 

    private IAuthenticationManager AuthenticationManager 
    { 
     get 
     { 
      return HttpContext.GetOwinContext().Authentication; 
     } 
    } 


    private async Task SignInAsync(ApplicationUser user, bool isPersistent) 
    { 
     AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie); 
     var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie); 
     AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity); 
    } 


    private void AddErrors(IdentityResult result) 
    { 
     foreach (var error in result.Errors) 
     { 
      ModelState.AddModelError("", error); 
     } 
    } 


    private bool HasPassword() 
    { 
     var user = UserManager.FindById(User.Identity.GetUserId()); 
     if (user != null) 
     { 
      return user.PasswordHash != null; 
     } 
     return false; 
    } 


    public enum ManageMessageId 
    { 
     ChangePasswordSuccess, 
     SetPasswordSuccess, 
     RemoveLoginSuccess, 
     Error 
    } 


    private ActionResult RedirectToLocal(string returnUrl) 
    { 
     if (Url.IsLocalUrl(returnUrl)) 
     { 
      return Redirect(returnUrl); 
     } 
     else 
     { 
      return RedirectToAction("Index", "Home"); 
     } 
    } 

    #endregion 
} 

,編輯,查看

Catalog Controller edit view:`@model Catalog.Models.Partner 

@{ 
    ViewBag.Title = "Edit"; 
} 

<h2>Edit</h2> 


@using (Html.BeginForm("Edit", "Catalog", FormMethod.Post, new { enctype = "multipart/form-data" })) 
{ 
    @Html.AntiForgeryToken() 

    <div class="form-horizontal"> 
     <hr /> 
     @Html.ValidationSummary(true) 
     @Html.HiddenFor(model => model.ID) 

     <div class="form-group"> 
      @Html.LabelFor(model => model.Company, new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.TextBoxFor(model => model.Company, new { @class = "form-control", autocomplete = "off" }) 
       @Html.ValidationMessageFor(model => model.Company) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.Description, new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.TextBoxFor(model => model.Description, new { @class = "form-control", autocomplete = "off" }) 
       @Html.ValidationMessageFor(model => model.Description) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.Details, new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.TextAreaFor(model => model.Details, new { @class = "form-control", rows = 10 }) 
       @Html.ValidationMessageFor(model => model.Details) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.InCharge, new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.TextBoxFor(model => model.InCharge, new { @class = "form-control", autocomplete = "off" }) 
       @Html.ValidationMessageFor(model => model.InCharge) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.Email, new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.TextBoxFor(model => model.Email, new { @class = "form-control", autocomplete = "off" }) 
       @Html.ValidationMessageFor(model => model.Email) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.Logo, new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       <input type="file" name="file" /> 
      </div> 
     </div> 

     <div class="form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
       <input type="submit" value="Save" class="btn btn-default" /> 
      </div> 
     </div> 
    </div> 
} 
<hr /> 
<div> 
    @Html.ActionLink("Back to List", "Index") 
</div> 

@section Scripts { 
    @Scripts.Render("~/bundles/jqueryval") 
} 

`

+1

我想你應該只發布有關** **代碼! !無論如何,你嘗試在你的Login()方法(HttpPost之一)中使用簡單的Redirect()嗎?如果沒有任何錯誤檢查ReturnUrl,並且它不是...重定向到您喜歡的頁面。 –

回答

2

當斂數據庫上下文,添加Where()條款,只會抓住當前用戶所屬的信息至。如果你將其添加爲命名空間using Microsoft.AspNet.Identity;那麼你可以利用User.Identity.GetUserId()返回當前用戶的ID和使用,在您的Where()子句只瀏覽用戶/合作伙伴可以看到。

+0

我該如何去做這件事? – user3231232

+0

我需要看到在'Catalogs.Models.Partner'和表示公司的數據,所以我可以給你寫的代碼塊的數據庫表什麼。如果你不習慣展示它,只需給我一個類似於你正在使用的虛擬桌子。基本上,你只是想做一個'Where()'子句,它將等同於'GetUserId()',所以它只會顯示用戶鏈接公司的信息。 –

2

儘管問題的日期,我會在這裏留下我的答案,因爲這個問題是相關的,當你正在開發一個應用程序,面向需要讓只有登錄用戶查看,修改或刪除(或任何其他操作)的自己的記錄。

這個例子是使用實體框架和ASP.NET身份所示。

首先,你需要你的對象模型與用戶聯繫起來。這由IdentityUser表示。請注意,我們使用的是IdentityUser類,因爲我們使用的是ASP.NET身份,否則我們可以使用ClaimsIdentity

public class UserObject 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public IdentityUser User { get; set; } 
} 

這一點後,當您節省您的背景信息UserObject現場引用的IdentityUserId財產(這個類是AspNetUsers表的默認名稱)將與UserObject表一起創建。

然後爲了讓當前用戶呼叫HttpContext.GetOwinContext().Get<UserManager>()獲得UserManager,然後您撥打UserManager.FindById(User.Idendity.GetUserId())。只要記住在插入新對象時獲得與Owin上下文相關聯的IdentityDbContext,否則將引發異常。

public ActionResult Create(UserObjectViewModel uoViewModel) 
{ 
    UserObject uo = new UserObject(); 

    // create the UserObject using the properties from the UserObjectViewModel 
    ... 

    // get the User Manager 
    UserManager userManager = HttpContext.GetOwinContext().Get<UserManager>(); 

    // assign the current User 
    uo.User = userManager.FindById(User.Identity.GetUserId()) 

    ... 
} 

從現在起,你可以撥打User.Identity.GetUserId()來獲取當前用戶ID和您的查詢參數這樣一起發送:

public ActionResult Get() 
{ 
    string currentUserId = User.Identity.GetUserId(); 

    yourDbContext.Where(uo => uo.User.Id == currentUserId); 

    ... 
}