I have created a simply WCF web service and require WCF Security with username/password added to the service and have read through the following MS documentation https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-use-a-custom-user-name-and-password-validator to try and do so.
However, I am getting the error below when I run the project and go to http://localhost:50533/Service.svc:
Server Error in '/' Application.
Could not load file or assembly 'CustomUserNameValidator' or one of its dependencies. The system cannot find the file specified.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.IO.FileNotFoundException: Could not load file or assembly 'CustomUserNameValidator' or one of its dependencies. The system cannot find the file specified.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Assembly Load Trace: The following information can be helpful to determine why the assembly 'CustomUserNameValidator' could not be loaded.
=== Pre-bind state information ===
LOG: DisplayName = CustomUserNameValidator
(Partial)
WRN: Partial binding information was supplied for an assembly:
WRN: Assembly Name: CustomUserNameValidator | Domain ID: 6
WRN: A partial bind occurs when only part of the assembly display name is provided.
WRN: This might result in the binder loading an incorrect assembly.
WRN: It is recommended to provide a fully specified textual identity for the assembly,
WRN: that consists of the simple name, version, culture, and public key token.
WRN: See whitepaper http://go.microsoft.com/fwlink/?LinkId=109270 for more information and common solutions to this issue.
LOG: Appbase = file:///C:/Users/xxxx/source/repos/Misc/WCFDummyService/WCFDummyService/
LOG: Initial PrivatePath = C:\Users\xxxx\source\repos\Misc\WCFDummyService\WCFDummyService\bin
Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Users\xxxx\source\repos\Misc\WCFDummyService\WCFDummyService\web.config
LOG: Using host configuration file: C:\Users\xxxx\Documents\IISExpress\config\aspnet.config
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Users/xxxx/AppData/Local/Temp/Temporary ASP.NET Files/vs/2193ee9a/db4d60f6/CustomUserNameValidator.DLL.
LOG: Attempting download of new URL file:///C:/Users/xxxx/AppData/Local/Temp/Temporary ASP.NET Files/vs/2193ee9a/db4d60f6/CustomUserNameValidator/CustomUserNameValidator.DLL.
LOG: Attempting download of new URL file:///C:/Users/xxxx/source/repos/Misc/WCFDummyService/WCFDummyService/bin/CustomUserNameValidator.DLL.
LOG: Attempting download of new URL file:///C:/Users/xxxx/source/repos/Misc/WCFDummyService/WCFDummyService/bin/CustomUserNameValidator/CustomUserNameValidator.DLL.
LOG: Attempting download of new URL file:///C:/Users/xxxx/AppData/Local/Temp/Temporary ASP.NET Files/vs/2193ee9a/db4d60f6/CustomUserNameValidator.EXE.
LOG: Attempting download of new URL file:///C:/Users/xxxx/AppData/Local/Temp/Temporary ASP.NET Files/vs/2193ee9a/db4d60f6/CustomUserNameValidator/CustomUserNameValidator.EXE.
LOG: Attempting download of new URL file:///C:/Users/xxxx/source/repos/Misc/WCFDummyService/WCFDummyService/bin/CustomUserNameValidator.EXE.
LOG: Attempting download of new URL file:///C:/Users/xxxx/source/repos/Misc/WCFDummyService/WCFDummyService/bin/CustomUserNameValidator/CustomUserNameValidator.EXE.
Stack Trace:
[FileNotFoundException: Could not load file or assembly 'CustomUserNameValidator' or one of its dependencies. The system cannot find the file specified.]
System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName, ObjectHandleOnStack type) +0
System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName) +71
System.RuntimeType.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark) +41
System.Type.GetType(String typeName, Boolean throwOnError) +35
System.ServiceModel.Configuration.UserNameServiceElement.ApplyConfiguration(UserNamePasswordServiceCredential userName) +356
System.ServiceModel.Configuration.ServiceCredentialsElement.ApplyConfiguration(ServiceCredentials behavior) +128
System.ServiceModel.Configuration.ServiceCredentialsElement.CreateBehavior() +165
System.ServiceModel.Description.ConfigLoader.LoadBehaviors(ServiceModelExtensionCollectionElement`1 behaviorElement, KeyedByTypeCollection`1 behaviors, Boolean commonBehaviors) +204
System.ServiceModel.Description.ConfigLoader.LoadServiceDescription(ServiceHostBase host, ServiceDescription description, ServiceElement serviceElement, Action`1 addBaseAddress, Boolean skipHost) +13502205
System.ServiceModel.ServiceHostBase.LoadConfigurationSectionInternal(ConfigLoader configLoader, ServiceDescription description, ServiceElement serviceSection) +74
System.ServiceModel.ServiceHostBase.ApplyConfiguration() +188
System.ServiceModel.ServiceHost.ApplyConfiguration() +65
System.ServiceModel.ServiceHostBase.InitializeDescription(UriSchemeKeyedCollection baseAddresses) +188
System.ServiceModel.ServiceHost.InitializeDescription(Type serviceType, UriSchemeKeyedCollection baseAddresses) +49
System.ServiceModel.ServiceHost..ctor(Type serviceType, Uri[] baseAddresses) +153
System.ServiceModel.Activation.ServiceHostFactory.CreateServiceHost(Type serviceType, Uri[] baseAddresses) +34
System.ServiceModel.Activation.ServiceHostFactory.CreateServiceHost(String constructorString, Uri[] baseAddresses) +538
System.ServiceModel.HostingManager.CreateService(String normalizedVirtualPath, EventTraceActivity eventTraceActivity) +1489
System.ServiceModel.HostingManager.ActivateService(ServiceActivationInfo serviceActivationInfo, EventTraceActivity eventTraceActivity) +53
System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath, EventTraceActivity eventTraceActivity) +666
[ServiceActivationException: The service '/Service.svc' cannot be activated due to an exception during compilation. The exception message is: Could not load file or assembly 'CustomUserNameValidator' or one of its dependencies. The system cannot find the file specified..]
System.Runtime.AsyncResult.End(IAsyncResult result) +513025
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result) +182
System.ServiceModel.Activation.ServiceHttpHandler.EndProcessRequest(IAsyncResult result) +12
System.Web.CallHandlerExecutionStep.InvokeEndHandler(IAsyncResult ar) +161
System.Web.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar) +128
I have noticed this error only appears due to adding the following into my Web.Config file
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WCFDummyService.CustomUserNameValidator, CustomUserNameValidator" />
</serviceCredentials>
I've modified the value in customUserNamePasswordValidatorType numerous times to try and fix it but the error still comes up or a similar one.
See below for the full Web.Config file.
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
</appSettings>
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.6"/>
<httpRuntime targetFramework="4.6"/>
<pages>
<namespaces>
<add namespace="System.Runtime.Serialization"/>
<add namespace="System.ServiceModel"/>
<add namespace="System.ServiceModel.Web"/>
</namespaces>
</pages>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="Binding1">
<security mode="Transport">
<message clientCredentialType="UserName" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WCFDummyService.CustomUserNameValidator, CustomUserNameValidator" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
The Code is simply the default WCF Service code you get out of the box when creating a new WCF Service project in Visual Studio and I've just added a new CustomUserNameValidator class.
If you want to see this class, here is the code for it:
Imports System.IdentityModel.Selectors
Public Class CustomUserNameValidator
Inherits UserNamePasswordValidator
Public Overrides Sub Validate(ByVal userName As String, ByVal password As String)
If userName Is Nothing OrElse password Is Nothing Then
Throw New ArgumentNullException()
End If
If Not (userName = "user" AndAlso password = "pass123") Then
Throw New FaultException("Unknown Username or Incorrect Password")
End If
End Sub
End Class
Also, this is all that shows in Properties for the file.
If you can please help with the error, that would be very much appreciated.
The reason I was getting the problem above was because I needed to set this in the web.config
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="CustomUserNameValidator, App_Code" />
</serviceCredentials>
When I went to the following path on my machine, the only dll was App_Code.tjgywzog.dll so figured the assembly is just App_Code and then it just has to use the class name CustomUserNameValidator since my code is not using namespaces.