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

  • Home
  • SEARCH
  • 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 830887
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 15, 20262026-05-15T04:07:01+00:00 2026-05-15T04:07:01+00:00

I’m trying to create a custom authentication plugin for WMS 2009 in C#. I

  • 0

I’m trying to create a custom authentication plugin for WMS 2009 in C#.

I managed to implement something that for some reason blocks all requests…

[ComVisible(true)]
[Guid("C0A0B38C-C4FE-43B5-BE9E-C100A83BBCEE")]
public class AuthenticationPlugin : IWMSBasicPlugin, IWMSAuthenticationPlugin, IWMSAuthenticationContext
    private const string SubKey = "SOFTWARE\\Microsoft\\Windows Media\\Server\\RegisteredPlugins\\Authentication\\{C0A0B38C-C4FE-43B5-BE9E-C100A83BBCEE}";

    [ComRegisterFunction]
    public static void RegisterFunction(Type t)
    {
        try
        {
            RegistryKey regHKLM = Registry.LocalMachine;
            regHKLM = regHKLM.CreateSubKey(SubKey);
            regHKLM.SetValue(null, "UC WMS Authentication plugin");

            RegistryKey regHKCR = Registry.ClassesRoot;
            regHKCR = regHKCR.CreateSubKey("CLSID\\{C0A0B38C-C4FE-43B5-BE9E-C100A83BBCEE}\\Properties");
            regHKCR.SetValue("Name", CustomC WMS Authentication plugin");
            regHKCR.SetValue("Author", "Me");
            regHKCR.SetValue("CopyRight", "Copyright 2009. All rights reserved");
            regHKCR.SetValue("Description", "Enables custom WMS authentication");
        }
        catch (Exception error)
        {
            Console.WriteLine(error.Message, "Inside RegisterFunction(). Cannot Register.");
        }
    }

    [ComUnregisterFunction]
    public static void UnRegisterFunction(Type t)
    {
        try
        {
            RegistryKey regHKLM = Registry.LocalMachine;
            regHKLM.DeleteSubKey(SubKey);

            RegistryKey regHKCR = Registry.ClassesRoot;
            regHKCR.DeleteSubKeyTree("CLSID\\{C0A0B38C-C4FE-43B5-BE9E-C100A83BBCEE}");
            regHKCR.DeleteSubKeyTree("CSEventTest.CSEventPlugin");
        }
        catch (Exception error)
        {
            Console.WriteLine(error.Message, "Cannot delete a subkey.");
        }
    }

    #region IWMSBasicPlugin Members

    public void InitializePlugin(IWMSContext serverContext, WMSNamedValues namedValues, IWMSClassObject classFactory)
    {
    }

    public void ShutdownPlugin()
    {
    }

    public void EnablePlugin(ref int flags, ref int heartbeatPeriod)
    {
    }

    public void DisablePlugin()
    {
    }

    public object GetCustomAdminInterface()
    {
        return null;
    }

    public void OnHeartbeat()
    {
    }

    #endregion

    #region IWMSAuthenticationPlugin Members

    public IWMSAuthenticationContext CreateAuthenticationContext()
    {
        return (IWMSAuthenticationContext)this;
    }

    public int GetFlags()
    {
        return Convert.ToInt32(WMS_AUTHENTICATION_FLAGS.WMS_AUTHENTICATION_ANONYMOUS, CultureInfo.InvariantCulture);
    }

    public string GetPackageName()
    {
        return "Custom WMS Authentication";
    }

    public string GetProtocolName()
    {
        return "Basic";
    }

    #endregion

    #region IWMSAuthenticationContext Members

    public void Authenticate(object responseBlob, IWMSContext userContext, IWMSContext presentationContext, IWMSCommandContext commandContext, IWMSAuthenticationCallback callBack, object context)
    {
        callBack.OnAuthenticateComplete(WMS_AUTHENTICATION_RESULT.WMS_AUTHENTICATION_SUCCESS, null, context);
    }

    public IWMSAuthenticationPlugin GetAuthenticationPlugin()
    {
        return (IWMSAuthenticationPlugin)this;
    }

    public string GetImpersonationAccountName()
    {
        return String.Empty;
    }

    public int GetImpersonationToken()
    {
        return 0;
    }

    public string GetLogicalUserID()
    {
        return this.GetImpersonationAccountName();
    }

    #endregion
}

Can anyone spot why this is happening?

Also, is there any way I could have a look at the code for the standard Anonymous Authentication plugin already installed on the server? Is it in an assembly somewhere?

Thanks.

  • 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-15T04:07:02+00:00Added an answer on May 15, 2026 at 4:07 am

    I ran into the same issue. It isn’t enough to return success status from the Authenticate method.

    Your implemented method must retrieve a handle to a valid Windows Login. Search the net for C# examples of how to call this method: http://msdn.microsoft.com/en-us/library/aa378184%28VS.85%29.aspx

    bool result = LogonAPI.LogonUser("username", "domain", "password", LogonAPI.LOGON32_LOGON_NETWORK, LogonAPI.LOGON32_PROVIDER_DEFAULT, ref _userToken);
    

    Store the IntPtr you get back from the LogonUser call and implement the GetImpersonationToken method like so:

    public int GetImpersonationToken()
    {
        return _userToken.ToInt32();
    }
    

    Somehow the plug-in is able to tie that integer value back to a real windows account. I created a local account on the server that was in the Power Users group and used its username and password in the LogonUser method with the server being the domain. Once it is able to do so, the media should stream.

    My whole IWMSAuthenticationPlugin is as follows (it uses basic authentication):

    public class AuthenticationContext : IWMSAuthenticationContext
    {
    #region IWMSAuthenticationContext Members
    
    private WMS_AUTHENTICATION_RESULT _result;
    
    private readonly IWMSAuthenticationPlugin _plugin;
    private Credentials _credentials;
    private IntPtr _userToken;
    
    public AuthenticationContext(IWMSAuthenticationPlugin plugin)
    {
        _plugin = plugin;
    }
    
    public void Authenticate(object responseBlob, IWMSContext pUserCtx, IWMSContext pPresentationCtx, IWMSCommandContext pCommandContext, IWMSAuthenticationCallback pCallback, object context)
    {
        // must be Unicode.  If it isn't, the 
        // challenge isn't sent correctly
        Encoding enc = Encoding.Unicode;
        byte[] response;
        byte[] challenge = enc.GetBytes("");
    
        try
        {
            response = (byte[])responseBlob;
            if (response.Length == 0)
            {
                // The client requested authentication; prepare the
                // challenge response to send to the client.  In order to 
                // do Basic authentication, be sure to return "Basic" from 
                // your implementation of IWMSAuthenticationPlugin.GetProtocolName()
                string challengeTxt = "WWW-Authenticate: Basic realm=\"Domain\"";
                challenge = enc.GetBytes(challengeTxt);
    
                _result = WMS_AUTHENTICATION_RESULT.WMS_AUTHENTICATION_CONTINUE;
            }
            else
            {
                // parses Base64 encoded response and gets passed in credentials
                SetCredentials(enc.GetString(response));
    
                LdapConnection ldc = new LdapConnection("Domain");
                NetworkCredential nc = new NetworkCredential(_credentials.Username, _credentials.Password, "Domain");
                ldc.Credential = nc;
                ldc.AuthType = AuthType.Negotiate;
                ldc.Bind(nc); // user has authenticated at this point, as the credentials were used to login to the dc.
    
                // must log in with a local windows account and get a handle for the account.
                // even if success is returned, the plugin still needs a valid windows account
                // to stream the file.                    
                bool result = LogonAPI.LogonUser("local username", "local domain", "local password", LogonAPI.LOGON32_LOGON_NETWORK, LogonAPI.LOGON32_PROVIDER_DEFAULT, ref _userToken);
                _result = WMS_AUTHENTICATION_RESULT.WMS_AUTHENTICATION_SUCCESS;
            }
        }
        catch (LdapException e)
        {
            _result = WMS_AUTHENTICATION_RESULT.WMS_AUTHENTICATION_DENIED;
        }
        catch (Exception e)
        {
            _result = WMS_AUTHENTICATION_RESULT.WMS_AUTHENTICATION_ERROR;
        }
        finally
        {
            pCallback.OnAuthenticateComplete(_result, challenge, context);
        }
    }
    
    public IWMSAuthenticationPlugin GetAuthenticationPlugin()
    {
        return _plugin;
    }
    
    public string GetImpersonationAccountName()
    {
        return "Domain\\" + _credentials.Username;
    }
    
    public int GetImpersonationToken()
    {
        // somehow the plugin knows how this integer ties to a windows account.
        return _userToken.ToInt32();
    }
    
    public string GetLogicalUserID()
    {
        return GetImpersonationAccountName();
    }
    
    public void SetCredentials(string responseStr)
    {
        // for whatever reason, the responseStr has an extra character
        // tacked on the end that blows up the conversion.  When converting
        // from the Base64 string, remove that last character.
        string decoded = new UTF8Encoding().GetString(Convert.FromBase64String(responseStr.Substring(0, responseStr.Length - 1)));
    
        // now that the string has been decoded and is now in the format
        // username:password, parse it further into a Username and Password 
        // struct.
        _credentials = new Credentials(decoded);
    }
    
    #endregion
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm trying to create an if statement in PHP that prevents a single post
Basically, what I'm trying to create is a page of div tags, each has
For some reason, after submitting a string like this Jack’s Spindle from a text
I'm parsing an RSS feed that has an ’ in it. SimpleXML turns this
I am trying to understand how to use SyndicationItem to display feed which is
link Im having trouble converting the html entites into html characters, (&# 8217;) i
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I have just tried to save a simple *.rtf file with some websites and
I have a string like this: La Torre Eiffel paragonata all’Everest What PHP function
I've got a string that has curly quotes in it. I'd like to replace

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.