MOSS 관련 도구를 ASPX로 만들때 종종 아래와 같은 SPException에 빠져 작업을 할 수 없는 경우가 있다.
"이 페이지에 대한 보안 유효성 검사가 잘못되었습니다. 웹 브라우저에서 [뒤로] 단추를 클릭하고 페이지를 새로 고친 다음 작업을 다시 시도하십시오." [ The security validation for this page is invalid. Click Back in your Web browser ]
초기에는 해당 페이지의 보안 유효성의 문제에 대한 정확한 정의를 알지 못해 오로지 짐작으로만 대략 파악하고 있어, 이에 대한 대처 방안이 전혀 없었다.
혼자 만의 짐작으로는 한개의 ASPX 내에서 너무 다양한 일을 수행하여 Page 자체의 Time-Out 이 걸렸거나, 아니면 SPList를 수정하는 도중 SPListItem의 설정을 동시에 수정하려 하거나 해서 발생하는 것이라 판단했었다.
그러나 어느것 하나 명확치 않았고, 더욱이 해결 방법이 너무 모호해서 알수 없었다.
이 중 헤딩 끝에 간신히 나름 '이거다!' 라고 판단 된 부분만을 언급하도록 하겠다.
1. 위치가 다른 자원을 접근 시도 할 때.
보통 관리용 ASPX 페이지를 작성 한 뒤, 이 페이지를 접근할 때 http://hostname/_layouts/xxxxx.aspx 이런 식으로 하게 된다. 그런데, 만일 저 xxxxx.aspx 페이지 내에 다른 사이트의 SPSite를 열어서 그 안의 값을 수정하는 경우에 바로 페이지 보안 오류가 발생한다.
다시 정리하자면, http://hostname/_layouts/xxxxx.aspx 를 띄운 뒤,
내부 코드에서 SPSite site = new SPSite("http://hostname/sites/childsite") 라는 코드가 들어 있고, 저 site 라는 변수를 통해 web을 얻고(site.RootWeb) 그 web의 Title을 수정하는 경우다.
즉 xxxx.aspx 페이지는 hostname 이라는 Site에서 띄운 것인데, xxxx.aspx 페이지안에서 처리하는 사이트는 hostname/sites/childsite 인 것이다. MOSS 입장에서는 hostname에 소속된 xxxx.aspx 페이지 주제에 다른 site의 자원을 접근하여 처리하는 것을 용납하지 못한다는 의미로 판단하면 된다.
이 경우, 여러 사이트의 자원을 일괄적으로 변경할 필요가 있다면, 별도 Windows Application으로 만들거나, STSADM에 명령어를 추가 구성해서 STSADM을 이용하여 변경하도록 한다.
만일 굳이 ASPX로 하고 싶다면, 저 ASPX에서 해당 사이트로 Redirect 하여, xxxx.aspx를 다시 띄우도록 한다.
즉 this.Response.Redirect("http://hostname/sites/childsite/_layouts/xxxxx.aspx") 라고 해서 xxxx.aspx를 다시 실행하는 것이다.
2. 페이지에 대한 401에러 대처 기능 부재.
아마도 대부분이 이 경우에서 걸리는 경우로 들 수 있다.
보통 application.master나 default.master와 같은 MOSS 내에서 제공되는 Master 페이지를 이용하여 구성하는 경우 이 에러가 발생하지 않는데, 유독 독자적인 ASPX 페이지를 만드는 경우 발생하게 된다. 즉 빈 ASPX 페이지를 만든 뒤, 그 안에 자신이 만든 각종 코드를 넣어 실행하면 바로 페이지 보안 오류가 발생하게 된다.
그렇다고 default.master나 application.master 를 쓰자니 디자인 커스터마이징 할 때는 쥐약인 것이다.
그럼 왜 default.master와 application.master를 끼면 괜찮고, 빈 ASPX 페이지로 구성하면 이런 문제가 발생하는 것일까? 그 이유는 바로 401 에러를 의도적으로 내는 MOSS의 문제로 판단된다.
HttpWatcher 라는 HTTP 프로토콜 송수신 패킷을 확인해 보면, MOSS에서는 항상 ASPX 페이지를 띄울 때 의도적으로 401 에러를 유발하게 되는데, 애석하게도 이 경우 페이지 내 코드에서는 모든 경우에 SPException으로 떨어지게 된다.
그렇다면 우리가 만들 ASPX 페이지에서는 이 에러를 피해 갈 수 없을까?
의외로 간단하게 해결 될 수 있다.
일단 우리가 만드는 ASPX 페이지내에 <form runat="server" /> 가 필요하다. ASPX 페이지를 만들었다면 당연히 들어 있겠지만, 혹시나 해서 언급한다. 일단 Server 컨트롤 로써 동작하는 <form>을 만들어 주고, 그 안에
<SharePoint:FormDigest runat=server/>
를 넣어주도록 한다. 그러면 최소한 401 에러가 떨어지는 부분에 대해서는 페이지 처리 없이 넘어가고 그 뒤에 실제 코드를 실행해 주게 된다.
몇가지 더 확인해보고 검토해봐야 겠지만, 위의 2가지 경우가 현재로는 대부분 발생되는 문제로 생각되며, 그 이후에 추가적으로 발견되면 리포트 하도록 할 예정이다.