2013-04-10 5 views
1

webservicehost 클래스의 인증이 인증 표준에 완전히 부합하지 않는다는 사실을 알고 있습니다. 사용자가 잘못된 자격 증명을 입력하면 다른 자격 증명을 요구하는 대신 403이 반환됩니다.WebServiceHost 인증을 구현하는 방법은 무엇입니까?

작은 기본 프로젝트에 대한 내 요구 사항에 맞게 기본 인증 (세션 시작시 사용자 이름과 비밀번호, HTTPS 불필요 - 아래 그림 참조)을 구현하고 싶습니다. 다음과 같이

The type of authentication I want

내가는 myService에 대해 가지고있는 코드는 다음과 같습니다

Imports System.IO 
Imports System.Text 
Imports System.ServiceModel 
Imports System.ServiceModel.Web 
Imports System.ServiceModel.Channels 

<ServiceContract()> 
Public Class myService 
    <OperationContract(), WebGet(UriTemplate:="/xml/{argument1}/{argument2}")> 
    Public Function XML(argument1 As String, argument2 As String) As Stream 
     requestCounter += 1 
     Console.WriteLine("xml data request at " & DateTime.Now.ToString() & ", request count= " & requestCounter) 
     Console.WriteLine(WebOperationContext.Current.IncomingRequest.UserAgent.ToString()) 
     Return _ReturnXML("<xmlresponse><data><argument1>" & argument1 & "</argument1><argument2>" & argument2 & "</argument2></data><server><serverlivesince>" & serverStart.ToString() & "</serverlivesince><pageservetime>" & DateTime.Now.ToString() & "</pageservetime><requestcount>" & requestCounter & "</requestcount></server></xmlresponse>") 
     'returns the first two parameters, and the time and date 
    End Function 

    Private Shared Function _ReturnXML(_result As String) As Stream 
     Dim data = Encoding.UTF8.GetBytes(_result) 

     WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml; charset=utf-8" 
     WebOperationContext.Current.OutgoingResponse.ContentLength = data.Length 

     Return New MemoryStream(data) 
    End Function 
End Class 

나는 다음 HTML을 반환뿐만 아니라 다른 매개 변수를 조합하여 유사한 코드가 있습니다. 내 Main 클래스에서

인스턴스화하고이 서비스를 연 I :

Dim varWebService = New WebServiceHost(GetType(MyWebService), New Uri("http://0.0.0.0/")) 
varWebService.Open() 

는 사람이 간단한 인증을 구현하는 코드로 날을 제공 할 수 있을까요? 아니면 철저한 튜토리얼을 가르쳐 주시겠습니까? 어떤 도움 주셔서 감사합니다

+1

당신이 무엇을하려고 않은 것입니까? 너는 무엇을 얻었 느냐? 너는 무엇을 기대 했는가? –

+0

나는 아직 아무 것도 시도하지 않았다. 그것에 관해서도 아무런 단서도 없다. – rabbitt

+0

Stack Overflow는 일반적으로 특정 문제가있는 질문에 우호적이다. 우리는 아이디어를 요구하는 질문을 싫어하는 경향이 있습니다. –

답변

2

사용자 정의 WebServiceHost를 상속 받아 작성할 수 있으며 아래의 기본 매개 변수를 변경할 수 있습니다.

코드에서 유일한 변화는

Dim varWebService = New AuthenticatedWebServiceHost(GetType(MyWebService), New Uri("http://0.0.0.0/")) 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.IdentityModel; 
using System.IdentityModel.Selectors; 
using System.ServiceModel; 
using System.ServiceModel.Web; 
using System.ServiceModel.Security; 
using System.ServiceModel.Description; 

namespace StackOverflow 
{ 
    public class AuthenticatedWebServiceHost : WebServiceHost 
    { 
     public AuthenticatedWebServiceHost(Type type, Uri url) 
     { 
      IDictionary<string, ContractDescription> desc = null; 
      base.InitializeDescription(type, new UriSchemeKeyedCollection()); 
      base.CreateDescription(out desc); 
      var val = desc.Values.First(); 

      WebHttpBinding binding = new WebHttpBinding(); 
      binding.Security.Mode = WebHttpSecurityMode.TransportCredentialOnly; 
      binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic; 

      base.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom; 
      base.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomUserNamePasswordValidator(); 

      base.AddServiceEndpoint(val.ContractType, binding, url); 
     } 

     //Possible next question: 
     //"How can I get the name of the authenticated user?" 
     public static string UserName 
     { 
      get 
      { 
       if (OperationContext.Current == null) return null; 
       if (OperationContext.Current.ServiceSecurityContext == null) return null; 
       if (OperationContext.Current.ServiceSecurityContext.PrimaryIdentity == null) return null; 
       return OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name; 
      } 
     } 



     public class CustomUserNamePasswordValidator : UserNamePasswordValidator 
     { 
      public override void Validate(string userName, string password) 
      { 
       //Your logic to validate username/password 
       if (userName != password) 
        throw new SecurityAccessDeniedException(); 
      } 
     } 
    } 
} 
+0

나는 이것이 실제로 작동하는 것처럼 보일 수 없다. 샘플 함수가있는 예제 프로젝트를 제공 할 수 있을까요? 감사, – rabbitt

관련 문제