ASP.NET Identity 2.2.1을 사용하여 사용자 관리 시스템에서 역할(Role)을 관리하는 방법을 알아봅니다. 이 기능은 사용자에게 특정 권한을 부여하고 시스템 접근을 제어하는 데 필수적입니다.
RolesAdminController 구현
역할 관리를 담당할 RolesAdminController를 생성합니다. 기존 MVC 프로젝트의 Controllers 폴더에 마우스 오른쪽 버튼을 클릭하고 "추가" > "컨트롤러"를 선택한 후, "MVC 5 컨트롤러 - 비어 있음" 템플릿을 사용하여 RolesAdminController.cs 파일을 만듭니다.
액세스 제어 설정
컨트롤러의 모든 작업에 관리자(Admin) 역할만 접근할 수 있도록 [Authorize(Roles = "Admin")] 속성을 클래스 레벨에 추가합니다.
컨트롤러 종속성 주입
ApplicationUserManager 및 ApplicationRoleManager를 컨트롤러에서 사용할 수 있도록 종속성 주입을 설정합니다. 이는 Owin 컨텍스트를 통해 관리자 인스턴스를 가져오도록 구성합니다.
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using YourProject.Models; // 네임스페이스를 실제 프로젝트에 맞게 수정하세요.
[Authorize(Roles = "Admin")]
public class RolesAdminController : Controller
{
// 기본 생성자
public RolesAdminController()
{
}
// 종속성 주입을 위한 생성자
public RolesAdminController(ApplicationUserManager userManager, ApplicationRoleManager roleManager)
{
UserManager = userManager;
RoleManager = roleManager;
}
private ApplicationUserManager _userManager;
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
set
{
_userManager = value;
}
}
private ApplicationRoleManager _roleManager;
public ApplicationRoleManager RoleManager
{
get
{
return _roleManager ?? HttpContext.GetOwinContext().Get<ApplicationRoleManager>();
}
private set
{
_roleManager = value;
}
}
// ... (이하 액션 메서드)
}
역할 목록 표시 (Index)
모든 역할을 조회하여 뷰에 전달하는 Index 액션 메서드를 구현합니다.
/// <summary>
/// 역할 목록을 표시합니다.
/// </summary>
/// <returns>역할 목록 뷰</returns>
public ActionResult Index()
{
return View(RoleManager.Roles);
}
역할 상세 정보 보기 (Details)
특정 역할의 상세 정보와 해당 역할을 가진 사용자 목록을 조회하는 Details 액션 메서드를 구현합니다. 역할 ID를 매개변수로 받습니다.
using System.Net;
using System.Collections.Generic;
using System.Linq;
/// <summary>
/// 특정 역할의 상세 정보와 해당 역할을 가진 사용자 목록을 비동기적으로 조회합니다.
/// </summary>
/// <param name="id">조회할 역할의 ID</param>
/// <returns>역할 상세 정보 뷰</returns>
public async Task<ActionResult> Details(string id)
{
if (string.IsNullOrEmpty(id))
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var role = await RoleManager.FindByIdAsync(id);
if (role == null)
{
return HttpNotFound();
}
// 해당 역할에 속한 사용자 목록 조회
var usersInRole = new List<ApplicationUser>();
foreach (var user in UserManager.Users.ToList())
{
if (await UserManager.IsInRoleAsync(user.Id, role.Name))
{
usersInRole.Add(user);
}
}
ViewBag.Users = usersInRole;
ViewBag.UserCount = usersInRole.Count;
return View(role);
}
역할 생성 (Create)
새로운 역할을 생성하는 Create 액션 메서드를 구현합니다. GET 요청 시에는 생성 폼을 표시하고, POST 요청 시에는 입력된 정보를 바탕으로 역할을 생성합니다.
using YourProject.ViewModels; // RoleViewModel의 네임스페이스를 지정하세요.
/// <summary>
/// 역할 생성 폼을 표시합니다.
/// </summary>
/// <returns>역할 생성 뷰</returns>
public ActionResult Create()
{
return View();
}
/// <summary>
/// 비동기적으로 새로운 역할을 생성합니다.
/// </summary>
/// <param name="roleViewModel">생성할 역할 정보</param>
/// <returns>역할 목록 뷰로 리디렉션</returns>
[HttpPost]
public async Task<ActionResult> Create(RoleViewModel roleViewModel)
{
if (ModelState.IsValid)
{
var newRole = new IdentityRole(roleViewModel.Name);
var result = await RoleManager.CreateAsync(newRole);
if (!result.Succeeded)
{
// 생성 실패 시 오류 메시지 표시
ModelState.AddModelError("", result.Errors.First());
return View();
}
return RedirectToAction("Index");
}
return View();
}
역할 수정 (Edit)
기존 역할을 수정하는 Edit 액션 메서드를 구현합니다. GET 요청 시에는 수정할 역할 정보를 불러오고, POST 요청 시에는 변경된 내용을 저장합니다. [ValidateAntiForgeryToken] 속성을 사용하여 CSRF 공격을 방지합니다.
/// <summary>
/// 특정 역할의 수정 폼을 비동기적으로 표시합니다.
/// </summary>
/// <param name="id">수정할 역할의 ID</param>
/// <returns>역할 수정 뷰</returns>
public async Task<ActionResult> Edit(string id)
{
if (string.IsNullOrEmpty(id))
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var role = await RoleManager.FindByIdAsync(id);
if (role == null)
{
return HttpNotFound();
}
var roleModel = new RoleViewModel { Id = role.Id, Name = role.Name };
return View(roleModel);
}
/// <summary>
/// 비동기적으로 역할을 수정합니다.
/// </summary>
/// <param name="roleModel">수정할 역할 정보</param>
/// <returns>역할 목록 뷰로 리디렉션</returns>
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "Name,Id")] RoleViewModel roleModel)
{
if (ModelState.IsValid)
{
var existingRole = await RoleManager.FindByIdAsync(roleModel.Id);
if (existingRole == null)
{
return HttpNotFound();
}
existingRole.Name = roleModel.Name;
await RoleManager.UpdateAsync(existingRole);
return RedirectToAction("Index");
}
return View();
}
역할 삭제 (Delete)
역할을 삭제하는 Delete 액션 메서드를 구현합니다. GET 요청 시에는 삭제 확인 폼을 표시하고, POST 요청 시에는 역할을 삭제합니다. 삭제 시 해당 역할을 가진 사용자를 어떻게 처리할지에 대한 로직을 포함할 수 있습니다 (예: 사용자에게서 역할 제거 또는 역할 삭제 자체 불가).
/// <summary>
/// 특정 역할의 삭제 확인 폼을 비동기적으로 표시합니다.
/// </summary>
/// <param name="id">삭제할 역할의 ID</param>
/// <returns>역할 삭제 확인 뷰</returns>
public async Task<ActionResult> Delete(string id)
{
if (string.IsNullOrEmpty(id))
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var role = await RoleManager.FindByIdAsync(id);
if (role == null)
{
return HttpNotFound();
}
return View(role);
}
/// <summary>
/// 비동기적으로 역할을 삭제합니다.
/// </summary>
/// <param name="id">삭제할 역할의 ID</param>
/// <param name="deleteUser">(선택 사항) 사용자를 함께 삭제할지 여부 관련 파라미터 (구현에 따라 사용)</param>
/// <returns>역할 목록 뷰로 리디렉션</returns>
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> DeleteConfirmed(string id, string deleteUser)
{
if (ModelState.IsValid)
{
if (string.IsNullOrEmpty(id))
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var role = await RoleManager.FindByIdAsync(id);
if (role == null)
{
return HttpNotFound();
}
// 실제 삭제 로직 구현. 여기서는 역할만 삭제합니다.
// deleteUser 파라미터 등을 활용하여 사용자 처리 로직 추가 가능
var result = await RoleManager.DeleteAsync(role);
if (!result.Succeeded)
{
ModelState.AddModelError("", result.Errors.First());
// 삭제 실패 시, 삭제 확인 뷰를 다시 표시
return View(role);
}
return RedirectToAction("Index");
}
// ModelState가 유효하지 않은 경우
return View();
}
이상의 코드를 통해 ASP.NET Identity 2.2.1 환경에서 역할 관리 기능을 구현할 수 있습니다.