얼마전 ASP.NET의 공격자가 암호화된 데이터나 시스템정보를 획득할 수 있는 보안 취약성이 발표되었고,
방어를 위한 방법들이 안내되었는데, 오늘 해당 취약성에 대한 업데이트가 공개되었습니다.
빨리 서비스중인 ASP.NET 서비스에 빨리 적용하시어, 피해가 없도록 해주세요.

자세한 내용은 아래에서 확인하실 수 있습니다.

취약성 내용 : Important: ASP.NET Security Vulnerability
대처방안 : Update on ASP.NET Vulnerability
업데이트 소개 및 다운로드: ASP.NET Security Update Now Available

업데이트만 설치하시면 기존에 대처방안으로 안내된 작업은 하실 필요가 없습니다.
저작자 표시 동일 조건 변경 허락
Posted by WHiSTLE

트랙백 주소 http://blog.ntils.com/trackback/61 관련글 쓰기

댓글을 달아 주세요

ASP.NET 프로젝트에서는 Visual Studio에서 참조된 어셈블리 외에도 bin 폴더에 포함된 모든 어셈블리를 참조된 어셈블리로 인식합니다.
외부에서 컴파일 된 어셈블리 또한 런타임에 bin폴더로 추가하여도 정상적으로 동작하게 됩니다.

그렇다면, ASP.NET 프로젝트에서 참조된 모든 어셈블리의 목록을 어떻게 가져올 수 있을까요?
이는 System.Web.Compliation.BuildManager 클래스의 GetReferencedAssemblies 정적 메서드를 이용하여 알 수 있습니다.

만일 참조된 어셈블리에 존재하는 WCF RIA Services의 DomainService의 하위 클래스의 목록을 가져오려 한다면 아래와 같은 코드를 이용할 수 있습니다.

Dictionary<string, Type> dictionary = new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase);

Type type = typeof(DomainService);

 

foreach (Assembly assembly in BuildManager.GetReferencedAssemblies().Cast<Assembly>())

{

    Type[] exportedTypes = null;

    try

    {

        exportedTypes = assembly.GetExportedTypes();

    }

    catch (ReflectionTypeLoadException exception)

    {

        exportedTypes = exception.Types;

    }

    catch (Exception)

    {

    }

 

    if (exportedTypes != null)

    {

        foreach (Type type2 in exportedTypes)

        {

            if ((!type2.IsAbstract && !type2.IsInterface) &&

                (!type2.IsValueType && type.IsAssignableFrom(type2)) &&

                (TypeDescriptor.GetAttributes(type2)[typeof(EnableClientAccessAttribute)] != null))

            {

                string canonicalFileName = GetCanonicalFileName(type2);

                dictionary[canonicalFileName] = type2;

            }

        }

    }

}

위 코드에서는 BuildManager.GetReferencedAssemblies 메서드를 통하여 참조로 등록된 어셈블리들을 가져오고,
Type.IsAssignableFrom(Type) 메서드를 이용하여 현재 타입이 DomainService를 상속받고 있는지를 확인합니다.
그리고, TypeDescriptor.GetAttributes 메서드를 이용하여 등록된 특성 중에 EnableClientAccess 가 있는지를 확인하게 됩니다.

위와 같은 방식으로 BuildManager 클래스와 리플렉션을 이용하여 런타임에 참조된 어셈블리를 불러와서 다양한 활용이 가능해집니다.

Posted by WHiSTLE

트랙백 주소 http://blog.ntils.com/trackback/52 관련글 쓰기

댓글을 달아 주세요

간혹 사용자 정의 컨트롤(.ascx) 파일에서 처리한 내용을 Page에 바로 출력하는 것이 아니라, 문자열로 받아야 할 경우가 있습니다.
ASP.NET 웹 폼의 경우에는 Page.LoadControl() 과 Control.RenderControl() 메서드를 이용하여 아래와 같은 코드로 사용자 정의 컨트롤이 처리한 내용을 문자열로 받아올 수 있습니다.

Control control = LoadControl("~/MailTemplate.ascx");

 

((MailTemplate)control).DestinationName = "Whistle";

 

StringBuilder stringBuilder = new StringBuilder();

using (StringWriter sw = new StringWriter(stringBuilder))

{

    using (HtmlTextWriter tw = new HtmlTextWriter(sw))

    {

        control.RenderControl(tw);

    }

}

 

string messageContent = stringBuilder.ToString();

ASP.NET 웹 폼은 자체가 Page 클래스를 상속받으므로, TemplateControl.LoadControl() 메서드를 사용할 수 있으므로, 사용자 정의 컨트롤을 로드하고 HtmlTextWriter를 이용하여 컨트롤의 실행된 내용을 문자열로 받아 올 수 있습니다.

ASP.NET MVC는 사용자 정의 컨트롤이 ViewUserContol을 상속받게 되며, MVC Controller는 자체적으로 ViewUserControl에 대한 LoadControl을 제공하지 않습니다,
ViewUserControl 클래스의 인스턴스를 생성은 ViewPage 클래스의 인스턴스 상에서만 가능합니다.

즉, MVC에서 사용자 정의 컨트롤이 생성하는 HTML을 문자열로 받기 위해서는, 가상의 ViewPage의 인스턴스를 생성하고, 그 ViewPage를 기반으로 사용자 정의 컨트롤을 생성한 후 ASP.NET 웹 폼에서와 같은 방법으로 문자열을 받아 올 수 있습니다.

ViewData["UserName"] = "Whistle";

 

ViewPage viewPage = new ViewPage() { ViewContext = new ViewContext() };

 

viewPage.ViewData = new ViewDataDictionary(ViewData);

viewPage.Controls.Add(viewPage.LoadControl("~/Views/Shared/MailTemplate.ascx"));

 

StringBuilder sb = new StringBuilder();

using (StringWriter sw = new StringWriter(sb))

{

    using (HtmlTextWriter tw = new HtmlTextWriter(sw))

    {

        viewPage.RenderControl(tw);

    }

}

 

string message = sb.ToString();

위와 같은 형식으로 MVC에서도 사용자 정의 컨트롤의 출력 내용을 문자열로 받아와서 처리가 가능합니다.

Posted by WHiSTLE

트랙백 주소 http://blog.ntils.com/trackback/50 관련글 쓰기

댓글을 달아 주세요

얼마 전 한 신입사원이 데이터베이스에 저장되어 있는 BLOB형태의 이미지 파일을 ASP.NET 웹페이지로 출력하기 위해서, 데이터베이스에서 byte배열을 얻어서 하드디스크에 GUID형태의 이름을 가지는 이미지로 저장한 다음 그 파일을 출력하고, 이미지를 생성할때 마다 파일이 생성될 폴더에 파일 중 생성시간이 하루 이상 지난파일을 삭제하는 로직으로 짜고 있는것을 본적이 있었습니다.

검색엔진에 검색 한번으로 엄청난 양의 레퍼런스 코드가 쏟아져 나올텐데도, 자기 나름대로 계획을 세우고 꿋꿋하게 그걸 구현해 나가는 모습을 보고 얘한테 뭐라고해야하나 말아야하나 고민을 했었더랬습니다.

당시에는 핸들러파일(ashx)파일에서 이미지를 출력하도록하는 방법을 알려주고 끝냈었는데, 오늘 보니 Micorosft에서 ASP.NET Generated Image 라는 상당히 유용해 보이는 컨트롤을 내놓았네요.

서버 컨트롤형태로 구현되어 있고, 각 용도별 구현을 위해서 ImageHandler를 상속받는 ashx 핸들러 파일을 생성하여 컨트롤에 지정하도록 하고 있습니다.
즉, 이미지관련 처리를 위한 라이브러리를 제공하고 그 라이브러리를 이용해서 실제 이미지를 그리는 부분은 사용자에게 맡기는 형태입니다.

예제를 한번 보자면, 페이지에 컨트롤을 올리면
captured_Image.png 
디자인뷰 코드상에서 보면

<cc1:GeneratedImage ID="GeneratedImage1" runat="server" 
    ImageHandlerUrl="~/ImageHandler1.ashx" >
    <Parameters>
      <cc1:ImageParameter Name="Msg" Value="Welcome To CodeDigest" />
      </Parameters>
</cc1:GeneratedImage>
이미지를 처리할 대상을 ImageHandler1.ashx 로 설정하였습니다.
즉, 이미지 출력에 관한 모든 것은 ImageHandler1.ashx가 처리하는 것입니다.
ImageHandler1.ashx는 아래와 같습니다.
<%@ WebHandler Language="C#" Class="ImageHandler1" %>
 
using System;
using System.Collections.Specialized;
using System.Drawing;
using System.Web;
using Microsoft.Web;
 
public class ImageHandler1 : ImageHandler {
    
    public ImageHandler1() {
        // Set caching settings and add image transformations here       
       }
    
    public override ImageInfo GenerateImage(NameValueCollection parameters) {
        // Add image generation logic here and return an instance of ImageInfo
        Bitmap bit = new Bitmap(500, 500);
        Graphics gra = Graphics.FromImage(bit);
        gra.Clear(Color.AliceBlue);
        gra.DrawString(parameters["Msg"], new Font("Verdana", 16), Brushes.Black,0 , 150);
        this.ImageTransforms.Add(new WaterMark());
        return new ImageInfo(bit);
    }
}

위 코드는 새로운 Bitmap을 생성하서 그 안에 매개변수로 넘어온 메시지를 드로잉하여 반환합니다.
그러므로, 이 예제의 결과는 아래와 같습니다.
captured_Image.png[5]

하지만, 지정한 핸들러파일의 GenerateImage메서드의 구현에 따라서 이미지는 어떠한 형태로도 출력이 가능해 집니다.
DB에서 이미지를 불러와서 출력하는 것도 가능하고, 이미지의 리사이즈 및 이미지에 워터마크를 넣고, 테두리를 입히는 작업등 구현에 따라 다른 형태의 이미지를 출력할 수 있을것입니다.

컨트롤의 다운로드는 여기서 가능하시고, .NET Framework 3.5 SP1이 적용되어야 사용이 가능합니다.

좀더 자세한 내용 및 관련 예제은 다음 글 에서 확인이 가능합니다.
New Image Generator control in ASP.Net 3.5

Posted by WHiSTLE

트랙백 주소 http://blog.ntils.com/trackback/43 관련글 쓰기

댓글을 달아 주세요

집에 있는 데스크톱 컴퓨터에 문제가 생겨서 포맷을 하고 재설치중입니다.
운영체제 및 업데이트는 대충 다 이뤄진듯 하고 이제 Visual Studio를 설치하고 개발환경을 셋팅하고 있는데요.
그동안은 집에서는 영문버전 Visual Studio를 사용했었는데 이번에는 아무리 찾아도 영문판 Visual Studio 설치DVD가 보이질 않아서 어쩔수 없이 한글판 Visual Studio를 설치하였습니다.
얼마 전 Visual Studio 2008 SP1의 경우에는 이미 한글판이 출시되어 있어서 설치를 했습니다. 하지만, 이번 SP1의 경우에는 ASP.NET MVC 는 포함되지 않아서 아직 ASP.NET MVC의 경우에는 아직 한글판이 존재하지 않습니다. 물론, 현재 배포버전인 MVC Preview 3이후에 Preview 4가 나올 듯 하니 아직까지 정식버전 및 한글지원 버전은 좀 더 기다려야 할 듯 합니다.

하지만, 저같은 경우에는 이전에 MVC로 진행하던 것도 있고 해서 ASP.NET MVC Preview 3를 설치하였습니다. 설치시에는 문제가 없었지만, Visual Studio 실행시 새 프로젝트에서 "ASP.NET MVC Web Application" 프로젝트가 보이질 않았습니다. 설치는 정상적으로 이뤄졌는데, 프로젝트 템플릿이 제대로 로드가 되지 않는듯 하여, 인터넷을 뒤지기 시작했습니다.

역시, 제가 생각하는 것은 이미 다른 누군가가 고맙게도 해결책을 내놓아 두었더군요.
이번의 경우에는 taeyo.net에서 찾았습니다.

[MVC] MVC 애플리케이션 개발환경 설정 글과
VS2008 한글 RTM 설치후 추가 작업 해야할 것들 이라는 두개의 글에 걸쳐서 해결방법이 제시되어 있었습니다.

다음을 위해서 여기에 정리해 두자면,
설치후 프로젝트 템플릿이 로드 되지 않는 이유는 영문판과 한글판의 경우 프로젝트 템플릿이 저장되는 경로(버전)이 다르기 때문이며, 영문 버전(1033)폴더에 등록되어 있는 프로젝트 템플릿파일(zip파일)을 한글 버전(1042)폴더로 복사해 넣고, 등록과정을 거치면 사용이 가능합니다.
유의할 점은 ASP.NET MVC의 경우 WEB 프로젝트 외에 Test 프로젝트 템플릿도 함께 등록해줘야 합니다. ASP.NET MVC는 MVC용 테스트 프로젝트가 따로 존재하기 때문입니다.
그리고, 프로젝트에서 추가할 수 있는 Controller 클래스등의 아이템 템플릿들도 등록해야 합니다.

  1. ASP.NET MVC 프로젝트 템플릿 복사
    C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ProjectTemplates\CSharp\Web\1033 폴더(VS 영문판용 폴더)에 존재하는 MvcWebApplicationProjectTemplateP3.cs.zip 파일을
    C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ProjectTemplates\CSharp\Web\1042 폴더(VS 한글판용 폴더)로 복사한다.
  2. ASP.NET MVC용 테스트 프로젝트 템플릿 복사
    C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ProjectTemplates\CSharp\Test\1033 폴더(VS 영문판용 폴더)에 존재하는
    MvcWebApplicationTestProjectTemplateP3.cs 파일을
    C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ProjectTemplates\CSharp\Test\1042 폴더(VS 한글판용 폴더)로 복사한다.
  3. MVC용 아이템 템플릿을 생성
    MVC용 아이템 템플릿은 영문판용 폴더만 존재하고 한글판용 폴더는 존재하지 않습니다.
    C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates\CSharp\Web\MVC\1033 폴더에 포함된 파일들을
    C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates\CSharp\Web\MVC\1042 폴더를 새로 생성하여 추가합니다.
  4. Visual Studio 2008 명령 프롬프트에서
    devenv.exe /installvstemplates
    devenv.exe /setup

    명령을 실행한다.

MVC Project가 추가된 화면

Posted by WHiSTLE

트랙백 주소 http://blog.ntils.com/trackback/41 관련글 쓰기

댓글을 달아 주세요

ASP.NET 2.0에서 파일 다운로드를 구현할때 Respone.WriteFile을 이용해서 다운로드를 구현하였었는데, MSDN에는

큰 파일에 이 메서드를 사용하면 메서드 호출 시 예외가 발생할 수 있습니다. 이 메서드에 사용할 수 있는 파일의 크기는 웹 서버의 하드웨어 구성에 따라 다릅니다. 자세한 내용은 Microsoft 기술 자료에서 812406, "PRB: Response.WriteFile Cannot Download a Large File"을 참조하십시오.

라고 되어있습니다.

즉, 서버의 하드웨어에 따라 다운로드에 대한 한계가 존재한다는 것이겠죠?

 

하지만, HttpResponse 클래스에는 WirtFile메서드외에 TransmitFile메서드도 존재하는데, MSDN설명을 보면

지정된 파일을 메모리에 버퍼링하지 않고 HTTP 응답 출력 스트림에 직접 씁니다.

라고 되어 있습니다.( .NET 2.0에서 추가되었습니다.)

 

즉, 하드웨어의 구성에 관계없이 다운로드가 가능한 것이겠죠?

 

아직 정확한 성능의 차이점은 테스트를 하지않아 알지 못하지만, WriteFile에 대한 문제점을 해결하고자 MS에서 .NET Framework 2.0에서 추가한듯 합니다.(아니면 말구^^)

 

아래는 이미지등의 Internet Explorer자체에서 표시하는 파일형식도 모두 다운로드 대화상자를 이용하여 다운로드하는 코드입니다.

 

    1 Response.ContentType = "image/jpeg";

    2 Response.AppendHeader("Content-Disposition", "attachment; filename=NikeShox.jpg");

    3 Response.TransmitFile(@"D:\My Documents\My Pictures\기타 ScreenShots\042007000046.jpg");

    4 Response.End();

 

HTTP Header에 Content-Dispoition항목에다 attachment라는 값을 할당하였습니다.
Content-Disposition속성에다 attachment속성을 할당하면 브라우저에서 모든 확장자파일에 대하여 다운로드시 다운로드 대화상자를 뜨도록 하는 것이 가능합니다.

Posted by WHiSTLE

트랙백 주소 http://blog.ntils.com/trackback/22 관련글 쓰기

댓글을 달아 주세요

이전버튼 1 이전버튼