Partilhar via


SharePoint 2010의 사용자 지정 양식 로그인 페이지 작성: 2부

SharePoint 2010의 사용자 지정 양식 로그인 페이지 작성: 2부

이 게시물의 새로운 서론 부분 및 사이트 소유자에 대한 공개 의견:

블로그 사이트가 최신 버전으로 업그레이드되었다는데 어떤 눈부신 기능이 추가되었는지는 몰라도 독립 기념일에 내놓는 돼지 고기처럼 서식이 아주 형편없어졌습니다. 저는 평소에 이 새로운 버전에서 제공하는 형편 없는 태그(혹은 그 결여)를 임시 방편으로 처리하는 데 상당한 시간을 쏟아붓고 있습니다. 웹 마스터에게 얘기해서 게시물의 서식이 엉망으로 지정되어 있어 읽기가 상당히 불편하다고 알려 주시면 감사하겠습니다. 그 사이에 저는 시간이 허락될 때마다 작성한 원본 게시물을 포함하는 Word 문서를 첨부하겠습니다. 이러니 누가 기술이 쓸모있다고 하겠습니까? 자, 그럼 시작하겠습니다.

이 시리즈의 1부는 https://blogs.msdn.com/b/sharepoint_ko/archive/2010/11/17/sharepoint-2010-1.aspx에서 확인할 수 있으며 여기서는 완전히 새로운 양식 로그인 페이지를 만드는 방법에 대해 설명했습니다. 이러한 방법이 필요한 시나리오는 이중 인증과 같이 시스템 기본 UI에서 제공하는 것 이상의 기능이 필요한 경우입니다. 이 게시물에서는 다른 시나리오를 소개하겠습니다. 이 경우 시스템 기본 UI로도 충분하지만 로그인 시 추가적인 작업을 수행하려 합니다.

이 특별한 시나리오에서는 모든 사용자가 사이트에 처음 액세스하기 전에 해당 사이트의 사용 조건에 동의하게 하려고 합니다. 따라서 새 로그인 페이지를 만들어 시작하겠습니다. 또한 로그온 이벤트를 위한 처리기를 추가한 다음 이 이벤트에서 이러한 사용자에게 사용 조건에 동의했는지를 나타내는 쿠키가 있는지 확인하겠습니다. 쿠키가 없는 경우에는 동의함을 나타내는 확인란을 선택할 수 있는 페이지로 사용자를 리디렉션한 다음 다시 로그인 페이지로 리디렉션하도록 하겠습니다. 사용자가 다시 로그인하면 사용 조건 쿠키가 있다는 의미이므로 홈 페이지, 문서 등 사용자가 요청한 어떠한 리소스로든 탐색할 수 있도록 허용할 수 있습니다.

시작하기 위해 새 로그인 페이지를 만들겠습니다. 제 프로젝트에는 새 ASPX 페이지만 추가했습니다. 이 프로젝트에서는 Microsoft.SharePoint 및 Microsoft.SharePoint.IdentityModel에 대한 참조를 추가해야 합니다. Microsoft.SharePoint.IdentityModel에 대한 참조를 추가하는 방법에 대한 자세한 내용은 위의 링크에서 이 게시물의 1부를 참조하십시오. 제 페이지의 기반이 되는 코드에서 명령문을 사용하는 코드 모음을 다시 사용하겠습니다. 제가 사용한 것은 다음과 같습니다.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using Microsoft.SharePoint.IdentityModel.Pages;

using System.Diagnostics;

제가 작성하는 페이지는 양식 기반 인증을 위한 로그인 페이지이므로 FormsSignInPage를 상속해야 합니다. 따라서 클래스 선언은 다음과 같습니다.

public partial class AgreeLogin : FormsSignInPage

코드에서 첫 번째로 할 일은 페이지의 Load 이벤트를 재정의하는 것입니다. 여기서 페이지의 ASP.NET 로그인 컨트롤에 대한 로그인 이벤트 처리기를 추가하겠습니다. 다음은 페이지 로드를 위해 재정의된 형태입니다.

protected override void OnLoad(EventArgs e)

{

try

       {

             base.OnLoad(e);

             this.signInControl.LoggingIn +=

                   new LoginCancelEventHandler(signInControl_LoggingIn);

}

catch (Exception ex)

       {

       Debug.WriteLine(ex.Message);

       }

}

여기서 한 가지 주목할 부분은 try...catch 블록에 들어 있는 코드입니다. 이는 아래에서 설명하겠지만 페이지 태그가 잘못 사용된 상태에서 base.OnLoad(e)가 호출되면 오류를 발생하도록 하기 위해 집어넣은 것입니다. 다음에는 LoggingIn 이벤트 처리기의 구현을 소개하겠습니다.

void signInControl_LoggingIn(object sender, LoginCancelEventArgs e)

{

//look for a cookie; if not there then redirect to our accept terms page

       const string AGREE_COOKIE = "SignedTermsAgreement";

    try

       {

       //we want to check for our cookie here

              HttpCookieCollection cookies = HttpContext.Current.Request.Cookies;

              HttpCookie ck = cookies[AGREE_COOKIE];

              if (ck == null)

              //user doesn't have the cookie indicating that they've signed the

              //terms of use so redirect them

              Response.Redirect("AgreeTerms.aspx?" +

                     Request.QueryString.ToString());

}

       catch (Exception ex)

       {

       Debug.WriteLine("There was an error processing the request: " +

              ex.Message);

       }

}

제가 이 부분에서 하는 일은 로그인을 시작할 때 먼저 사용자가 사이트의 사용 조건에 동의했음을 나타내는 제 쿠키를 찾는 것입니다. 쿠키를 찾지 못하면 사용자가 제 AgreeTerms.aspx 페이지로 리디렉션됩니다. 로그인 페이지에서 수신된 전체 쿼리 문자열을 포함하는 이유는 이를 통해 로그인 페이지를 방문한 사용자가 요청한 리소스를 확인하여 사용 조건에 동의한 후 이들을 돌려보낼 위치를 알 수 있기 때문입니다. 여기서 주의해야 할 한 가지 중요한 사항은 사용 조건 페이지에 익명으로 액세스할 수 있도록 제 SharePoint 웹 응용 프로그램의 web.config를 변경해야 한다는 점입니다. 그렇지 않으면 사이트의 다른 모든 페이지처럼 보안이 유지된 리소스인 경우 무한 루프에 들어가게 됩니다. 즉, 쿠키가 없으면 저는 여러분을 AgreeTerms.aspx 페이지로 리디렉션하지만 이 페이지는 보안 페이지이므로 여러분은 다시 제 사용자 지정 로그인 페이지로 리디렉션되는 절차가 계속 반복되는 것입니다. 따라서 닫는 </system.web> 태그 바로 아래에 이 항목을 포함하도록 web.config를 수정했습니다.

<location path="_layouts/AgreeTerms.aspx">

<system.web>

<authorization>

<allow users="*" />

</authorization>

</system.web>

</location>

이제는 인증을 거치지 않고 제 AgreeTerms.aspx 페이지를 방문할 수 있습니다. 지금은 페이지의 UI로 여러분을 따분하게 하고 싶지는 않지만 이 페이지의 기반이 되는 코드에서는 UI가 매우 단순합니다.

protected void SubmitBtn_Click(object sender, EventArgs e)

{

const string AGREE_COOKIE = "SignedTermsAgreement";

try

       {

       //make sure the checkbox is checked

if ((AgreeChk.Checked) && (Request.Browser.Cookies))

              {

              //create the cookie

HttpCookie ck = new HttpCookie(AGREE_COOKIE, "true");

//set the expiration so it's persisted

ck.Expires = DateTime.Now.AddYears(3);

//write it out

HttpContext.Current.Response.Cookies.Add(ck);

//get the src attribute from the query string and redirect there

Response.Redirect(Request.QueryString["Source"]);

}

else

StatusLbl.Text = "You must agree to the terms of use before continuing.";

}

catch (Exception ex)

       {

       string msg = "There was an error processing the request: " + ex.Message;

       Debug.WriteLine(msg);

       StatusLbl.Text = msg;

}

}

이는 아주 명확해야 합니다. 즉, 여러분이 확인란을 선택하면 저는 쿠키를 제공하고 Response.Redirect를 통해 처음에 요청한 원본으로 여러분을 리디렉션합니다. 이렇게 되면 여러분은 다시 로그인 페이지로 돌아오게 되지만 이번에 로그인을 수행하면 쿠키가 확인되고 모든 부분이 정상적으로 작동하게 됩니다. 사용 조건에 동의하지 않으면 아무 곳으로도 이동하지 않게 됩니다.

코드 지정 측면에서는 이렇게만 하면 끝이지만 포함해야 할 또 다른 상당히 중요한 항목이 있는데, 그것은 바로 로그인 페이지의 태그입니다. 앞에서도 설명했지만 태그가 잘못되면 온갖 종류의 문제를 겪게 됩니다. 따라서 다음과 같은 태그를 사용하여 시작해야 합니다.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="AgreeLogin.aspx.cs" Inherits="FormsLoginPage.AgreeLogin,FormsLoginPage, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cf32e76ff986e00f" MasterPageFile="~/_layouts/simple.master" %>

<%@ Assembly Name="Microsoft.SharePoint.ApplicationPages, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>

<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %> <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Import Namespace="Microsoft.SharePoint" %>

<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<asp:Content ContentPlaceHolderId="PlaceHolderPageTitle" runat="server">

    <SharePoint:EncodedLiteral ID="ClaimsFormsPageTitle" runat="server" text="<%$Resources:wss,login_pagetitle%>" EncodeMethod='HtmlEncode'/>

</asp:Content>

<asp:Content ContentPlaceHolderId="PlaceHolderPageTitleInTitleArea" runat="server">

    <SharePoint:EncodedLiteral ID="ClaimsFormsPageTitleInTitleArea" runat="server" text="<%$Resources:wss,login_pagetitle%>" EncodeMethod='HtmlEncode'/>

</asp:Content>

<asp:Content ContentPlaceHolderId="PlaceHolderSiteName" runat="server"/>

<asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server">

<SharePoint:EncodedLiteral runat="server" EncodeMethod="HtmlEncode" ID="ClaimsFormsPageMessage" />

 <asp:login id="signInControl" FailureText="<%$Resources:wss,login_pageFailureText%>" runat="server" width="100%">

    <layouttemplate>

        <asp:label id="FailureText" class="ms-error" runat="server"/>

        <table class="ms-input">

          <colgroup>

          <col width="25%"/>

          <col width="75%"/>

          </colgroup>

        <tr>

            <td nowrap="nowrap"><SharePoint:EncodedLiteral ID="EncodedLiteral3" runat="server" text="<%$Resources:wss,login_pageUserName%>" EncodeMethod='HtmlEncode'/></td>

            <td><asp:textbox id="UserName" autocomplete="off" runat="server" class="ms-long ms-login-textbox"/></td>

        </tr>

        <tr>

            <td nowrap="nowrap"><SharePoint:EncodedLiteral ID="EncodedLiteral4" runat="server" text="<%$Resources:wss,login_pagePassword%>" EncodeMethod='HtmlEncode'/></td>

            <td><asp:textbox id="password" TextMode="Password" autocomplete="off" runat="server" class="ms-long ms-login-textbox"/></td>

        </tr>

        <tr>

            <td colspan="2" align="right"><asp:button id="login" commandname="Login" text="<%$Resources:wss,login_pagetitle%>" runat="server" /></td>

        </tr>

        <tr>

            <td colspan="2"><asp:CheckBox id="RememberMe" text="<%$SPHtmlEncodedResources:wss,login_pageRememberMe%>" runat="server" /></td>

        </tr>

        </table>

    </layouttemplate>

 </asp:login>

</asp:Content>

정말로 바꾸고 싶은 유일한 부분은 가장 첫 번째 줄인 @Page 지시문일 것입니다.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="AgreeLogin.aspx.cs" Inherits="FormsLoginPage.AgreeLogin,FormsLoginPage, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cf32e76ff986e00f" MasterPageFile="~/_layouts/simple.master" %>

노란색으로 강조 표시된 부분은 각자의 사용자 지정 어셈블리에 대한 강력한 이름이 되도록 변경해야 합니다.

이를 모두 통합하여 컴파일한 후에는 GAC에서 어셈블리를 등록하고 자신의 ASPX 페이지를 레이아웃 디렉터리에 복사하기만 하면 됩니다. 실제로 시험해 보기 전에 마지막으로 수행할 단계는 현재 FBA를 사용하는 웹 응용 프로그램 영역의 로그인 페이지를 변경하는 것입니다. 이렇게 하려면 중앙 관리에서 응용 프로그램 관리, 웹 응용 프로그램 관리로 이동합니다. 해당 웹 응용 프로그램을 선택한 다음 도구 모음에서 인증 공급자 단추를 클릭합니다. 변경할 영역의 링크를 클릭하면 나타나는 대화 상자에서 사용자 지정 로그인 페이지 라디오 단추를 클릭한 다음 해당 로그인 페이지의 URL을 입력합니다. 제 경우에는 _layouts/AgreeLogin.aspx였습니다. 변경 내용을 저장하면 사이트에 로그인할 준비를 마치게 됩니다.

마지막으로 제 사용자 지정 페이지로 사이트에 로그인했을 때 나타나는 모습을 소개하는 것으로 글을 마무리하겠습니다. 이 게시물에 나와 있는 대로 작업을 성공적으로 수행할 수 있기를 바랍니다.

1. 초기 로그인

2. 사용 조건 페이지

3. 원하는 사이트로 이동 가능

 

이 문서는 번역된 블로그 게시물입니다. 원본 문서는 SharePoint 2010의 사용자 지정 양식 로그인 페이지 작성: 2부를 참조하십시오.