2013. 9. 3. 18:35

'ASP.NET MVC'를 공부하면서 느끼는 게 많은데.....

그런 건 집어치우고;;

 

'ASP.NET MVC'의 자습서나 기본 생성 템플릿은 이전과 많이 다른 인증 방식을 보여 주고 있습니다.

마이크로소프트가 어련히 잘해놨겠지만 찝찝한 것들도 많고;;;

 

어찌됐건 기존 쓰던 세션 방식을 사용하면서도 편리한 필터를 사용하기 위해서는 인증용 필터를 따로 만들어야 합니다.

(기본 생성된 인증은..... 참고 자료일 뿐 완전히 고쳐야 합니다;;)

 

 

1. 필터 만들기

인증용 필터는 훈스닷넷에 풍술사님의 코드를 참고하여 만들었습니다.

(참고 : [5조] Filter - AuthorizeAttribute)

public enum UserType
{
	Admin = 1,
	Staff = 2,
	User = 3,
}

public class CustomAuthorizeAttribute : AuthorizeAttribute
{
	public new UserType Roles;  // new keyword will hide base class Roles Property
	protected override bool AuthorizeCore(HttpContextBase httpContext)
	{
		if (httpContext == null)
		{
			throw new ArgumentNullException("httpContext");
		}

		if (null == httpContext.Session[mvc_SessionAuthorize.claGlobal.SessionString_UserType]
			|| "" == httpContext.Session[mvc_SessionAuthorize.claGlobal.SessionString_UserType].ToString())
		{
			return false;
		}

		UserType role 
			= (UserType)Convert.ToInt32( httpContext.Session[mvc_SessionAuthorize.claGlobal.SessionString_UserType]);

		// you could get User role or user type from session.

		if (Roles != 0 && ((Roles & role) != role))
		{
			return false;
		}
		return true;
	}
}

 

계정의 권한은 'UserType'로 정의합니다.

외부에서 필터를 호출하면 'public new UserType Roles;' 이곳에 저장이 됩니다.

 

이 코드는 각각의 권한에 대한 높낮이가 없습니다.

그래서 'Admin' 권한 이여도 'User' 권한이 없으면 'User' 권한 페이지를 볼 수 없습니다.

이 문제를 해결하려면 '[Flags]'를 이용하거나

ex>

[Flags]

public enum UserType

 

룰을 체크하는 코드

'if (Roles != 0 && ((Roles & role) != role))'

를 수정하여 원하는 방법으로 동작하게 할 수 있습니다.

 

만약 여기서 'false'가 리턴되면 401에러 페이지가 표시됩니다.

 

 

2. 테스트용 컨트롤러 만들기

이제 테스트용 컨트롤러를 만들어야 합니다.

테스트용이기 때문에 별도의 작업 없이 'HomeController.cs'를 생성하여 인덱스 페이지에서 작업을 하겠습니다.

테스트를 위해 별도의 id 인증작업은 하지 않고 유저가 입력한 대로 세션에 넣어 줍니다.

 

먼저 유저 정보를 받을 모델을 만듭니다.

public class UserInfoModels
{
	public string UserID { get; set; }
	public string UserPW { get; set; }
	public string UserType { get; set; }
}

 

 

'HomeController.cs'를 만듭니다.

public class HomeController : Controller
{
    // GET: /Home/
    public ActionResult Index()
    {
        return View();
    }

	[HttpPost]
	[ValidateAntiForgeryToken]
	public ActionResult Index(UserInfoModels model, string returnUrl, string btnSubmit)
	{
		switch (btnSubmit)
		{
			case "로그인":
				if (true == ModelState.IsValid)
				{
					//로그인 확인
					//이 예제에서는 뭘넣어도 로그인 성공으로 체크한다.
					int nReturn = 0;

					if (0 == nReturn)
					{

						//로그인성공
						Session[claGlobal.SessionString_UserID] = model.UserID;
						Session[claGlobal.SessionString_UserType] = UserType.User;

						return View();
					}
				}

				// 이 경우 오류가 발생한 것이므로 폼을 다시 표시하십시오.
				ModelState.AddModelError("", "제공한 사용자 이름 또는 암호가 잘못되었습니다.");
				break;

			case "로그아웃":
				Session[claGlobal.SessionString_UserID] = null;
				Session[claGlobal.SessionString_UserType] = null;
				break;
		}

		return View(model);
	}

	[CustomAuthorize(Roles = UserType.User)]
	public ActionResult Test()
	{
		return View();
	}

}

 

이 코드에서 보시면 '[CustomAuthorize(Roles = UserType.User)]' 이렇게 필터를 적용한 것을 알 수 있습니다.

이제 'Test()'에 연결된 뷰 페이지는 'User' 권한이 있어야지만 페이지를 볼 수 있습니다.

 

 

3. 테스트용 뷰 생성

이제 테스트용 뷰를 생성하겠습니다.

로그인이 만큼

id와 password를 받는 텍스트 필드

로그인/로그아웃 버튼

을 만들어야 합니다.

@model mvc_SessionAuthorize.Models.UserInfoModels

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>


@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) 
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>로그인 양식</legend>
        <ol>
            <li>
                @Html.LabelFor(m => m.UserID)
                @Html.TextBoxFor(m => m.UserID)
                @Html.ValidationMessageFor(m => m.UserID)
            </li>
            <li>
                @Html.LabelFor(m => m.UserPW)
                @Html.PasswordFor(m => m.UserPW)
                @Html.ValidationMessageFor(m => m.UserPW)
            </li>
        </ol>
        <input type="submit" name="btnSubmit" value="로그인" />
    </fieldset>

	
	if ( null != Session[mvc_SessionAuthorize.claGlobal.SessionString_UserID]
		&& "" != Session[mvc_SessionAuthorize.claGlobal.SessionString_UserID])
	{
		<text>
			로그인된 사용자 : @Session[mvc_SessionAuthorize.claGlobal.SessionString_UserID].ToString();<br />
			권한 : @Session[mvc_SessionAuthorize.claGlobal.SessionString_UserType].ToString();<br />
				<input name="btnSubmit" type="submit" value="로그아웃" />
		</text>
	}
	else
	{
		<text>
			로그인 해주세요~
		</text>
	}
}

<br />
@Html.ActionLink("테스트 페이지", "Test" );

 

 

이제 'Test()'에 연결된 뷰를 만들어야 하는데......

이 뷰는 별 의미는 없습니다-_-;

화면에 표시되는지 안 되는지만 확인하면 되죠.

@{
    ViewBag.Title = "Test";
}

<h2>Test</h2>

 

 

4. 테스트

드디어 테스트입니다.

 

로그인하고 안 함에 따라 테스트 페이지가 다르게 표시되고 있습니다.

 

 

마무리

이 글에서 사용된 테스트 프로젝트입니다.

mvc_SessionAuthorize.zip
다운로드

 

 

asp.net mvc를 공부하면서 옛날 악몽들이 다시 떠오르고 있습니다-_-;;;

나중에 기회가 되면 이야기하도록 하죠;;;

 

asp.net mvc 자습서가 기존 기술들과 합께 쓰는 방법에 대해서는 언급이 없어서 오히려 힘드네요;;;

"템플릿 잘돼 있으니 그냥 써라 ㅎ"

라는 느낌?