Organization Unit(OU) Delete

|

Oranization Unit(OU) 생성시 잘못된 삭제를 방지하기 위하여 기본적으로 Everyone 그룹의 권한을 상속 받습니다.

따라서 잘못 생성한 OU를 삭제하기 위해서는 권한을 제거 해야하며 대량의 삭제를 위해서는 각 각의 OU의 권한제거가 아닌 Everyone 그룹의 권한을 변경해야 합니다.

 

이번에는 생성된 OU에 설정된 권한을 확인하고 삭제하는 방법을 알아보도록 하겠습니다.

 

우선 생성한 OU을 삭제하려고 시도 하면 다음과 같이 에러가 발생합니다.

 

 

 

위 에러를 해결하기 위한 방법으로 아래 방법을 따라 합니다.

 

솔루션

1. 도메인 관리자 그룹의 사용자로 로그인.

2. Active Directory Users and Computers 실행

3. "View" 클릭 후 "Advanced Features" 클릭

 

 

 

4. 삭제하고자 하는 OU를 선택하고 마우스 오른쪽을 클릭하여 "Properties" 선택

 

 

 

5. OU 속성의 "Security" 탭을 선택하고 "Advanced" 클릭

 

 

 

6. "Permission Entries"에서 "Everyone" 그룹의 "Deny" 항목 선택 후 "Remove" 클릭

 

 

 

7. "OK" 클릭 후 "Advanced Security Settings" 닫고 OU 속성 창 닫기

 

 결과 화면입니다. OUTest OU가 정상적으로 삭제 되었습니다.

 

 

대량의 OU를 삭제하기 위해서는 Everyone의 권한을 상승하면 가능합니다.

 

 

'Programming > Active Directory' 카테고리의 다른 글

Organization Unit(OU) Delete  (0) 2013.05.23
Trackback 0 And Comment 0

[ASP.NET] HttpPostedFile 'NotSupportedException' Error

|

ASP.NET WebForm, MVC 등 웹 개발을 할 경우 Client에서 Server 단으로 파일을 업로드 해야할 경우가 빈번하다.

보통 파일 업로드를 구현하면서 생기는 경우가 대부분 일 것이라고 생각한다.

 

HttpPostedFile을 이용하여 파일을 서버단에 저장 할 경우 SaveAs Method를 이용할 경우가 있을텐대 이경우에 주의해야 할 점이 있다.

HttpPostedFile의 FileName은 Client 단에 파일 경로를 포함하고 있으므로 HttpPostedFile 의 FileName을 그대로 이용하여 파일을 저장 할 경우

 

'지정한 경로 형식은 지원되지 않습니다.'  와 같은 에러가 발생하게 된다.

 

File 명을 가져오기 위해서 여러가지 방법이 있을 수 있겠지만 가장 간단하게 사용할 수 있는 Path Static Class를 이용하여 파일명만 가져오면 문제는 쉽게 해결된다.

 

예제 소스

for (int i = 0; i < Request.Files.Count; i++)
{
    HttpPostedFile file = Request.Files[i];
    if (!Directory.Exists(@"D:\TEST"))
        Directory.CreateDirectory(@"D:\TEST");

    file.SaveAs(@"D:\TEST\" + Path.GetFileName(file.FileName));
}

 

'Programming > .NET' 카테고리의 다른 글

[ASP.NET] HttpPostedFile 'NotSupportedException' Error  (0) 2013.04.03
ASP.NET MVC Web API JSONP  (0) 2013.04.01
[ASP.NET] ASP.NET MVC 3 Routing 개념  (0) 2012.09.18
[ASP.NET] ASP.NET MVC 3 Model  (1) 2012.09.18
[ASP.NET] ASP.NET MVC 3 View  (1) 2012.09.18
[ASP.NET] ASP.NET MVC 3 Controller  (2) 2012.09.18
Trackback 0 And Comment 0

ASP.NET MVC Web API JSONP

|

Web Application을 개발함에 있어서 우리는 가끔 cross-site문제에 봉착하게 됩니다.

cross-site 문제로 브라우저에서는 다음과 같은 에러를 발생시켜 줍니다.


"SEC7128: Multiple Access-Control-Allow-Origin headers are not allowed for CORS response."


Cross Origin Resource Sharing (CORS) 라는 응답을 리턴 해주는데 이 오류를 우회하기 위한 대표적인 방법으로 JSONP 가 있습니다.


이 글에서는 ASP.NET MVC4 Web API 기반에서 JSONP를 사용하는 방법에 대해서 알아보도록 하겠습니다.

JSONP는 url에 응답으로 넘어올 JSON 데이터를 받아서 처리 할 수 있는 callback를 정의해서 callback내에서 응답을 처리하는 구조로 사용합니다.


예를 들면 다음과 같이 질의를 보내야 합니다.

Http://aaa.com/api/crossApi/GetValue?id=2&callback=myCallback


기본적으로 JSONP 는 ajax, XMLHttpRequest 객체를 사용할 수 없게 되어 있으며 JSONP를 사용하기 위해서는 script Tag를 사용하는 것이 통상적입니다.


Ajax를 사용하게 되면 다음과 같이 에러가 발생하게 됩니다. 




Script Tag를 이용하여 cross-site 접근하기 위해서는 다음과 같이 동적으로 추가를 하거나

var scriptTag = document.createElement("script");
scriptTag.src = "http:⁄⁄aaa.com⁄api⁄CrossApi⁄GetValue?id=2&callback=myCallback";
document.getElementsByTagName("head")[0].appendChild(scriptTag);

정적으로 추가하여 사용할 수 있습니다.

<script src="http:⁄⁄aaa.com⁄api⁄CrossApi⁄GetValue?id=2&callback=myCall" type="text⁄javascript"><⁄script>

위 두 방법을 사용하는데 있어서는 제약 사항이 많이 있을 수 있습니다. jQuery에서는 위 방법보다 유연한 메서드를 제공해주고 있으며 이를 이용하여 유연한 코딩이 가능해 집니다.

jQuery $.getJSON
$.getJSON("http:⁄⁄aaa.com⁄api⁄CrossApi⁄GetValue?callback=?", { id: "2" },
    function (data) {
        alert(data);
    });

Callback 파라미터의 값을 “?”로 지정하게 되면 동적으로 생성되는 자바스크립트 함수의 함수명이 되고 개발자 도구를 이용해서 확인하면 다음과 같이 동적으로 생성된 함수명이 넘어가는 것을 확인 할 수 있습니다.


http://aaa.com/api/CrossApi/GetValue?callback=jQuery19107003410930461618_1364716419821&id=test&_=1364716419827


JSONP는 비교적 간단한 프로토콜이라고 생각하면 될 것 같습니다.

JSON 응답과 함께 자바스크립트 함수를 호출하게 되는데 위의 URL의 응답을 확인해 보면 다음과 같습니다.

jQuery19107003410930461618_1364716419821({
  "id": "test",
  "name": "TEST"
})

요청을 보내는 Client에서는 위와 같이 JSONP를 사용할 수 있습니다.

그럼 이제 JSONP와 ASP.NET Web API에 대해서 살펴 보도록 하겠습니다.


ASP.NET Web API는 기본적으로 JSONP 를 지원하지 않습니다. 하지만 Fomatter를 이용하여 비교적 간단하게 JSONP를 지원해 줄 수 있습니다.


JsonpFormatter Class

public class JsonpFormatter : System.Net.Http.Formatting.JsonMediaTypeFormatter
    {
        private string JsonpCallbackFunction;
        
        public string JsonpParameterName { get; set; }
        
        ⁄⁄⁄ <summary>
        ⁄⁄⁄ 지원하는 헤더 추가 생성 및 JSONP 파라미터 이름 지정
        ⁄⁄⁄ <⁄summary>
        public JsonpFormatter() {
            SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("application⁄json"));
            SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text⁄javascript"));
 
            JsonpParameterName = "callback";
        }
 
        ⁄⁄⁄ <summary>
        ⁄⁄⁄ 특정 MediaTypeFormatter 인스턴스 반환
        ⁄⁄⁄ <⁄summary>
        public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type,
                                                                          HttpRequestMessage request,
                                                                          MediaTypeHeaderValue mediaType)
        {
            var formatter = new JsonpFormatter
            {
                JsonpCallbackFunction = GetJsonCallbackFunction(request)
            };
 
            formatter.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
            formatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
 
            return formatter;
        }
 
        ⁄⁄⁄ <summary>
        ⁄⁄⁄ 비동기 Stream Write
        ⁄⁄⁄ <⁄summary>
        public override System.Threading.Tasks.Task WriteToStreamAsync(Type type,
                                                                       object value,
                                                                       Stream writeStream,
                                                                       HttpContent content,
                                                                       TransportContext transportContext)
        {
            if (string.IsNullOrEmpty(JsonpCallbackFunction))
                return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
 
            StreamWriter writer = null;
 
            try
            {
                writer = new StreamWriter(writeStream);
                ⁄⁄ 응답으로 넘어 갈 때 Callback(JSON) 형식으로 넘어가게 된다.
                writer.Write(JsonpCallbackFunction + "(");
                writer.Flush();
            }
            catch (Exception ex)
            {
                try
                {
                    if (writer != null)
                        writer.Dispose();
                }
                catch { }
 
                var tcs = new TaskCompletionSource<object>();
                tcs.SetException(ex);
                return tcs.Task;
            }
 
            ⁄⁄ 응답으로 넘어 갈 때 Callback(JSON) 형식으로 넘어가게 된다.
            return base.WriteToStreamAsync(type, value, writeStream, content, transportContext)
                       .ContinueWith(innerTask =>
                       {
                           if (innerTask.Status == TaskStatus.RanToCompletion)
                           {
                               writer.Write(")");
                               writer.Flush();
                           }
 
                       }, TaskContinuationOptions.ExecuteSynchronously)
                        .ContinueWith(innerTask =>
                        {
                            writer.Dispose();
                            return innerTask;
 
                        }, TaskContinuationOptions.ExecuteSynchronously).Unwrap();
        }
 
        ⁄⁄⁄ <summary>
        ⁄⁄⁄ callback 함수명 반환
        ⁄⁄⁄ <⁄summary>
        private string GetJsonCallbackFunction(HttpRequestMessage request)
        {
            if (request.Method != HttpMethod.Get)
                return null;
 
            var query = HttpUtility.ParseQueryString(request.RequestUri.Query);
            var queryVal = query[this.JsonpParameterName];
 
            if (string.IsNullOrEmpty(queryVal))
                return null;
 
            return queryVal;
        }
    }

위 코드에서 보는 것과 같이 HttpRequest를 확인하여 질의에 callback이 존재하면 JSONP 형태(Callback(JSON)) 로 응답을 보내주게 됩니다.

이 JsonpFormatter 클래스는 GlobalConfiguration 정적 클래스를 통하여 Formatter Collection에 추가 할 수 있으며 해당 코드라인은 Global.asax에 위치하게 됩니다.


Global.asax

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
 
    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
         
    ⁄⁄ Formatter Collection에 JsonpFormatter 추가
    GlobalConfiguration.Configuration.Formatters.Insert(0, new AAA.Formatters.JsonpFormatter());
}

JSONP를 사용하기 위한 개발은 여기까지 입니다. 테스트를 위해서는 도메인 명이 다른 두 개의 사이트를 준비해야 하며 본인은 AAA와 BBB 두 개의 사이트를 생성하여 테스트 하였습니다.


테스트를 위한 IIS 구성은 다음과 같이 하였습니다.



BBB.com에서 AAA.com Web API로 JSON 데이터를 요청 하도록 구성하였습니다.

실행화면 입니다.



앞서 언급했듯이 jQuery의 getJSON메서드를 이용하였으며 ajax를 이용하기 위해서는 Access-Control-Allow-Origin을 추가 하면 될 수 있겠지만 이는 JSONP를 사용하는 의도와는 맞지 않기 때문에 ajax는 사용하지 않았습니다.

또한, JSONP는 보안상으로 취약점을 만들 수 있으니 신중하게 사용해야 할 것 같습니다.


소스파일은 첨부파일로 추가 하도록 하겠습니다.


 JsonpTestProject.zip


'Programming > .NET' 카테고리의 다른 글

[ASP.NET] HttpPostedFile 'NotSupportedException' Error  (0) 2013.04.03
ASP.NET MVC Web API JSONP  (0) 2013.04.01
[ASP.NET] ASP.NET MVC 3 Routing 개념  (0) 2012.09.18
[ASP.NET] ASP.NET MVC 3 Model  (1) 2012.09.18
[ASP.NET] ASP.NET MVC 3 View  (1) 2012.09.18
[ASP.NET] ASP.NET MVC 3 Controller  (2) 2012.09.18
Trackback 0 And Comment 0
prev | 1 | 2 | 3 | 4 | ··· | 13 | next