Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7414417
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 29, 20262026-05-29T07:05:50+00:00 2026-05-29T07:05:50+00:00

I have been following this tutorial in order to get username authentication with transport

  • 0

I have been following this tutorial in order to get username authentication with transport security working in my WCF service. The tutorial however refers to using basicHttpBinding which is unacceptable – I require wsHttpBinding.

The idea is to have a custom BasicAuthenticationModule on WCF service which would read the “Authorization” header from the HTTP request and perform the auth process according to “Authorization” header contents. The problem is that “Authorization” header is missing!

I have implemented IClientMessageInspector via custom behavior in order to manipulate outgoing messages and add custom SOAP headers. I have added the following code in BeforeSendRequest function:

    HttpRequestMessageProperty httpRequest = request.Properties.Where(x => x.Key == "httpRequest").Single().Value;
    httpRequest.Headers.Add("CustomHeader", "CustomValue");

This should work and according to many web resources, it works for basicHttpBinding but not wsHttpBinding. When I say “works”, I mean that the header is successfully received by WCF service.

This is the simplified function which inspects the received HTTP message on WCF service side:

    public void OnAuthenticateRequest(object source, EventArgs eventArgs)
    {
        HttpApplication app = (HttpApplication)source;

        //the Authorization header is checked if present
        string authHeader = app.Request.Headers["Authorization"];
        if (string.IsNullOrEmpty(authHeader))
        {
            app.Response.StatusCode = 401;
            app.Response.End();
        }
    }

Bottom posts of this thread dated september 2011 say that this is not possible with wsHttpBinding. I don’t want to accept that response.

As a side note, if I use the Basic Authentication Module built in IIS and not the custom one, I get

The parameter ‘username’ must not contain commas.** error message when trying Roles.IsInRole("RoleName") or `[PrincipalPermission(SecurityAction.Demand, Role = “RoleName”)]

probably because my PrimaryIdentity.Name property contains the certificate subject name as I am using TransportWithMessageCredential security with certificate-based message security.

I am open for suggestions as well as alternate approaches to the problem. Thanks.

UPDATE

As it seems, the HTTP header gets read correctly later throughout the WCF service code.
(HttpRequestMessageProperty)OperationContext.Current.IncomingMessageProperties["httpRequest"] contains my custom header. However, this is already message-level.. How to pass the header to transport authentication routine?

UPDATE 2
After a bit of a research, I came to a conclusion that, when a web browser receives HTTP status code 401, it presents me with the login dialog where I can specify my credentials. However a WCF client simply throws an exception and doesn’t want to send credentials. I was able to verify this behavior when visiting https://myserver/myservice/service.svc in Internet Explorer. Tried to fix using information from this link but to no avail. Is this a bug in WCF or am I missing something?

EDIT

Here are relevant sections from my system.servicemodel (from web.config) – I am pretty sure I got that configured right though.

  <serviceBehaviors>
    <behavior name="ServiceBehavior">
      <serviceMetadata httpsGetEnabled="true" httpGetEnabled="false" />
      <serviceDebug includeExceptionDetailInFaults="true" />
      <serviceCredentials>
        <clientCertificate>
          <authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck" />
        </clientCertificate>
        <serviceCertificate findValue="server.uprava.djurkovic-co.me" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My" />
      </serviceCredentials>
      <serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="AspNetSqlRoleProvider" />
    </behavior>
  </serviceBehaviors>
    ................
  <wsHttpBinding>
    <binding name="EndPointWSHTTP" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="20480000" maxReceivedMessageSize="20480000" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
      <readerQuotas maxDepth="20480000" maxStringContentLength="20480000" maxArrayLength="20480000" maxBytesPerRead="20480000" maxNameTableCharCount="20480000" />
      <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
      <security mode="TransportWithMessageCredential">
        <transport clientCredentialType="Basic" />
        <message clientCredentialType="Certificate" negotiateServiceCredential="true" algorithmSuite="Default" />
      </security>
    </binding>
  </wsHttpBinding>
    ............
  <service behaviorConfiguration="ServiceBehavior" name="DjurkovicService.Djurkovic">
    <endpoint address="" binding="wsHttpBinding" bindingConfiguration="EndPointWSHTTP" name="EndPointWSHTTP" contract="DjurkovicService.IDjurkovic" />
  </service>

The exception returned by the service is:

The HTTP request is unauthorized with client authentication scheme ‘Anonymous’. The authentication header received from the server was ‘Basic Realm,Negotiate,NTLM’. (The remote server returned an error: (401) Unauthorized.)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-29T07:05:51+00:00Added an answer on May 29, 2026 at 7:05 am

    Interestingly enough, while I was writing the last comment regarding the answer above, I stopped for a moment. My comment contained “…If the HTTP header doesn’t contain the “Authorization” header, I set the status to 401, which causes the exception.” I set the status to 401. Got it? The solution was there all along.

    The initial packet doesn’t contain the authorization header even if I explicitly add it. However each consequent packet does contain it as I have tested while having the authorization module inactive. So I though, why don’t I try to distinguish this initial packet from the others? So if I see that it’s the initial packet, set HTTP status code to 200 (OK), and if it’s not – check for authentication header. That was easy, since the initial packet sends a request for the security token in a SOAP envelope (Contains <t:RequestSecurityToken> tags).

    Ok so let’s take a look at my implementation, in case someone else would need it.

    This is the BasicAuthenticationModule implementation, which implements IHTTPModule:

    public class UserAuthenticator : IHttpModule
    {
        public void Dispose()
        {
        }
    
        public void Init(HttpApplication application)
        {
            application.AuthenticateRequest += new EventHandler(this.OnAuthenticateRequest);
            application.EndRequest += new EventHandler(this.OnEndRequest);
        }
    
        public void OnAuthenticateRequest(object source, EventArgs eventArgs)
        {
            HttpApplication app = (HttpApplication)source;
    
            // Get the request stream
            Stream httpStream = app.Request.InputStream;
    
            // I converted the stream to string so I can search for a known substring
            byte[] byteStream = new byte[httpStream.Length];
            httpStream.Read(byteStream, 0, (int)httpStream.Length);
            string strRequest = Encoding.ASCII.GetString(byteStream);
    
            // This is the end of the initial SOAP envelope
            // Not sure if the fastest way to do this but works fine
            int idx = strRequest.IndexOf("</t:RequestSecurityToken></s:Body></s:Envelope>", 0);
            httpStream.Seek(0, SeekOrigin.Begin);
            if (idx != -1)
            {
                // Initial packet found, do nothing (HTTP status code is set to 200)
                return;
            }
    
            //the Authorization header is checked if present
            string authHeader = app.Request.Headers["Authorization"];
            if (!string.IsNullOrEmpty(authHeader))
            {
                if (authHeader == null || authHeader.Length == 0)
                {
                    // No credentials; anonymous request
                    return;
                }
    
                authHeader = authHeader.Trim();
                if (authHeader.IndexOf("Basic", 0) != 0)
                {
                    // the header doesn't contain basic authorization token
                    // we will pass it along and
                    // assume someone else will handle it
                    return;
                }
    
                string encodedCredentials = authHeader.Substring(6);
    
                byte[] decodedBytes = Convert.FromBase64String(encodedCredentials);
                string s = new ASCIIEncoding().GetString(decodedBytes);
    
                string[] userPass = s.Split(new char[] { ':' });
                string username = userPass[0];
                string password = userPass[1];
                // the user is validated against the SqlMemberShipProvider
                // If it is validated then the roles are retrieved from 
                // the role provider and a generic principal is created
                // the generic principal is assigned to the user context
                // of the application
    
                if (Membership.ValidateUser(username, password))
                {
                    string[] roles = Roles.GetRolesForUser(username);
                    app.Context.User = new GenericPrincipal(new
                    GenericIdentity(username, "Membership Provider"), roles);
                }
                else
                {
                    DenyAccess(app);
                    return;
                }
            }
            else
            {
                app.Response.StatusCode = 401;
                app.Response.End();
            }
        }
    
        public void OnEndRequest(object source, EventArgs eventArgs)
        {
            // The authorization header is not present.
            // The status of response is set to 401 Access Denied.
            // We will now add the expected authorization method
            // to the response header, so the client knows
            // it needs to send credentials to authenticate
            if (HttpContext.Current.Response.StatusCode == 401)
            {
                HttpContext context = HttpContext.Current;
                context.Response.AddHeader("WWW-Authenticate", "Basic Realm");
            }
        }
    
        private void DenyAccess(HttpApplication app)
        {
            app.Response.StatusCode = 403;
            app.Response.StatusDescription = "Forbidden";
    
            // Write to response stream as well, to give the user 
            // visual indication of error 
            app.Response.Write("403 Forbidden");
    
            app.CompleteRequest();
        }
    }
    

    Important: in order for us to be able to read the http request stream, ASP.NET compatibility must not be enabled.

    To make your IIS load this module, you must add it to <system.webServer> section of web.config, like this:

    <system.webServer>
      <modules runAllManagedModulesForAllRequests="true">
        <remove name="BasicAuthenticationModule" />
        <add name="BasicAuthenticationModule" type="UserAuthenticator" />
      </modules>
    

    But before that, you must ensure BasicAuthenticationModule section is not locked, and it should be locked by default. You will not be able to replace it if it’s locked.

    To unlock the module: (note: I am using IIS 7.5)

    1. Open IIS Manager
    2. In the left pane, click on your host name
    3. In the middle pane, under “Management” section, open “Configuration Editor”
    4. Click the combo box next to “Section” label in the upper pane section, expand “system.webServer” then navigate to “modules”
    5. Under “(Collection)” key, click “(Count=nn)” value to have a small button with “…” appear. Click on it.
    6. In the “Items” list, find “BasicAuthenticationModule” and in the right pane click “Unlock Item” (if present!).
    7. If you changed this setting, close the Configuration Editor, saving changes.

    On the client side, you need to be able to add custom HTTP headers to the outgoing message. The best way to do this is to implement IClientMessageInspector and add your headers using the BeforeSendRequest function. I will not explain how to implement IClientMessageInspector, there are plenty of resources on that topic available online.

    To add the “Authorization” HTTP header to the message, do the following:

        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {    
    
            // Making sure we have a HttpRequestMessageProperty
            HttpRequestMessageProperty httpRequestMessageProperty;
            if (request.Properties.ContainsKey(HttpRequestMessageProperty.Name))
            {     
                httpRequestMessageProperty = request.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
                if (httpRequestMessageProperty == null)
                {      
                    httpRequestMessageProperty = new HttpRequestMessageProperty();
                    request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessageProperty);
                } 
            }
            else
            {     
                httpRequestMessageProperty = new HttpRequestMessageProperty();
                request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessageProperty);
            } 
            // Add the authorization header to the WCF request    
            httpRequestMessageProperty.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(Service.Proxy.ClientCredentials.UserName.UserName + ":" + Service.Proxy.ClientCredentials.UserName.Password)));
            return null;
        }    
    

    There ya go, it took a while to resolve but it was worth it, as I found many similar unanswered questions throughout the web.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have been following this Tutorial on how to read from a plist. However
I'm new to NHibernate... I have been following this NHibernate Tutorial from Gabriel Schenker
I've been battling to get this right...basically I have the following HTML setup: <div
I have been following this tutorial and everything was going nice and easy until
I've been following along with this excellent asio tutorial , but have got confused
i have been following this tutorial for the pagerAdapter. http://mobile.tutsplus.com/tutorials/android/android-user-interface-design-horizontal-view-paging/ My problem is that
I have been following this tutorial series for OpenGL : GLUT : http://www.lighthouse3d.com/opengl/glut/ I
I've been following this tutorial on how to create an OData service. http://www.hanselman.com/blog/CreatingAnODataAPIForStackOverflowIncludingXMLAndJSONIn30Minutes.aspx And
I've been following this tutorial (lesson 6) in order to build and deploy a
I have been following this tutorial, http://ruby.railstutorial.org/chapters/modeling-users?version=3.2#top , which I find great, but it

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.