programing

사용자 지정 WebAPI HttpMessageHandler에서 사용자 주체를 안전하게 설정하려면 어떻게 해야 합니까?

instargram 2023. 8. 25. 23:15
반응형

사용자 지정 WebAPI HttpMessageHandler에서 사용자 주체를 안전하게 설정하려면 어떻게 해야 합니까?

사용자 기본인위사용정의구다니습현했을 했습니다.HttpMessageHandlerDarin Dimitrov의 답변에 나온 예를 기반으로 합니다. https://stackoverflow.com/a/11536349/270591

코가인스만듭다니를스턴드를 .principalGenericPrincipal사용자 이름과 역할을 사용한 다음 이 주체를 스레드의 현재 주체로 설정합니다.

Thread.CurrentPrincipal = principal;

에서.ApiController 수 .User속성:

public class ValuesController : ApiController
{
    public void Post(TestModel model)
    {
        var user = User; // this should be the principal set in the handler
        //...
    }
}

최근에 사용자 정의를 추가하기 전까지는 이 작업이 잘 수행되는 것 같았습니다.MediaTypeFormatterTask so 라이브러리:

public override Task<object> ReadFromStreamAsync(Type type, Stream readStream,
    HttpContent content, IFormatterLogger formatterLogger)
{
    var task = Task.Factory.StartNew(() =>
    {
        // some formatting happens and finally a TestModel is returned,
        // simulated here by just an empty model
        return (object)new TestModel();
    });
    return task;
}

(는 (으)로 이 있습니다Task.Factory.StartNewReadFromStreamAsync어떤 샘플 코드로부터.그것이 잘못된 것이며 문제의 유일한 이유일 수도 있습니다.)

" - 에게는 무작위로 -가, "끔그고나" - 리게그무보로작위입다니그 - 에은것그▁now▁-▁-▁to다▁-▁random보▁be입니sometimes"▁the▁"▁appears▁it▁"무로.User더 . 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자 이름, 사용자Authenticated플래그 및 역할이 모두 손실되었습니다.그 이유는 사용자 지정 MediaTypeFormatter로 인해 MessageHandler와 컨트롤러 메서드 간에 스레드가 변경되었기 때문인 것 같습니다.나는 이것을 확인했다 가치들의 가치들을 비교함으로써.Thread.CurrentThread.ManagedThreadId메지처리및컨방법있습다니에러롤트시기▁". " " 교장선생님이 됩니다."때때로" 그들은 다르며 교장은 "잃어버린" 것입니다.

나는 이제 설정의 대안을 찾았습니다.Thread.CurrentPrincipal어떻게든 사용자 지정 MessageHandler에서 컨트롤러 메서드로 주체를 안전하게 전송하고 이 블로그 게시물 요청 속성을 사용합니다.

request.Properties.Add(HttpPropertyKeys.UserPrincipalKey,
    new GenericPrincipal(identity, new string[0]));

나는 그것을 테스트하고 싶었지만, 그것은.HttpPropertyKeys 공간에 )System.Web.Http.Hosting)가 .UserPrincipalKey최신 WebApi 버전에서는 더 이상 속성을 사용할 수 없습니다(지난 주의 릴리스 후보 및 최종 릴리스).

제 질문은:현재 WebAPI 버전에서 작동하도록 위의 마지막 코드 스니펫을 어떻게 변경할 수 있습니까?또는 일반적으로:사용자 지정 MessageHandler에서 사용자 주체를 설정하고 컨트롤러 방식으로 안정적으로 액세스하려면 어떻게 해야 합니까?

편집

여기서 언급되는 것은 "HttpPropertyKeys.UserPrincipalKey로 됩니다.“MS_UserPrincipal”그래서 저는 다음을 사용하려고 했습니다.

request.Properties.Add("MS_UserPrincipal",
    new GenericPrincipal(identity, new string[0]));

하지만 제가 기대했던 것처럼 작동하지 않습니다: The.ApiController.User에 속에추주없습에 되어 있지 .Properties위의 징수금

새 스레드에서 주체가 손실되는 문제는 다음과 같습니다.

http://leastprivilege.com/2012/06/25/important-setting-the-client-principal-in-asp-net-web-api/

중요:ASP에서 클라이언트 주체 설정.NET 웹 API

ASP 깊은 곳에 묻혀 있는 몇 가지 불행한 메커니즘 때문입니다.NET, 스레드를 설정합니다.웹 API 웹 호스팅의 현재 Principal로는 충분하지 않습니다.

ASP에서 호스팅하는 경우.NET, 스레드.현재 주체가 HttpContext로 재정의될 수 있습니다.현재의.새 스레드를 만들 때 사용합니다.즉, 스레드와 HTTP 컨텍스트 모두에서 주체를 설정해야 합니다.

그리고 여기: http://aspnetwebstack.codeplex.com/workitem/264

현재 웹 호스팅 시나리오에서 사용자 지정 메시지 처리기를 사용하여 인증을 수행하는 경우 사용자 권한에 대해 다음 두 가지를 모두 설정해야 합니다.

IPrincipal principal = new GenericPrincipal(
    new GenericIdentity("myuser"), new string[] { "myrole" });
Thread.CurrentPrincipal = principal;
HttpContext.Current.User = principal;

마지막 줄을 추가했습니다.HttpContext.Current.User = principal(계속)using System.Web;) 메시지 처리기 및 메시지 처리기에User의 재산.ApiControllerMediaTypeFormatter의 작업으로 인해 스레드가 변경된 경우에도 에서는 항상 올바른 주체를 가집니다.

편집

강조하기 위해: 현재 사용자의 주체 설정HttpContextWebApi가 ASP에서 호스팅되는 경우에만 필요합니다.NET/I는.자가 호스팅의 경우 필요하지 않습니다(그리고 다음과 같은 이유로 인해HttpContextASP입니다.NET은 자체 호스팅 시 구성되며 존재하지 않습니다.

컨스트전방면를사보십오시해용려지를 사용해 .TaskCompletionSource<object>사용자 정의에서 다른 태스크를 수동으로 시작하는 대신MediaTypeFormatter:

public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
    var tcs = new TaskCompletionSource<object>();

    // some formatting happens and finally a TestModel is returned,
    // simulated here by just an empty model
    var testModel = new TestModel();

    tcs.SetResult(testModel);
    return tcs.Task;
}

하여 MessageHandler를 할 수 .MS_UserPrincipal전화를 통한 재산.HttpRequestMessageExtensionMethods.SetUserPrincipal 확장방에서 정의한 System.ServiceModel.Channels:

protected override Task<HttpResponseMessage> SendAsync(
    HttpRequestMessage request, CancellationToken cancellationToken)
{
    var user = new GenericPrincipal(new GenericIdentity("UserID"), null);
    request.SetUserPrincipal(user);
    return base.SendAsync(request, cancellationToken);
}

이렇게 하면 이 속성이 요청의 속성 컬렉션에 추가될 뿐 ApiController에 연결된 사용자는 변경되지 않습니다.

언급URL : https://stackoverflow.com/questions/12028604/how-can-i-safely-set-the-user-principal-in-a-custom-webapi-httpmessagehandler

반응형