I have recently read the WCF Security Guide and am using it to create an application where users need to create their own account, and then access the application with message security. Below is the web.config file I have come up with so far from the book. The issue I am having revolves around user registration. Since the application requires username/password authentication, the method to register a new user consistently fails.
I know of one way around this (switching to role based authentication and creating a single user in a role that has registration privileges, and just hard coding that information into the registration method) but am seeking an alternative solution. Is there a way to declare, at the operation level, that a particular method does not require authentication? If not, is there a way to expose a separate endpoint with a different service contract, and have that contract not require authentication? So much of the web.config file is related to the membership provider and message security, I am a little concerned, but for the method to properly register a new member in the database it does have to know about the membership provider obviously...
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<connectionStrings>
<add name="MyLocalSQLServer"
connectionString="Initial Catalog=aspnetdb;data source=DESKTOP;Integrated Security=SSPI;"/>
</connectionStrings>
<system.web>
<authentication mode="Forms" />
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
<membership defaultProvider="MySqlMembershipProvider">
<providers>
<clear />
<add name="mySqlMembershipProvider"
connectionStringName="MyLocalSQLServer"
applicationName="Mech"
type="System.Web.Security.SqlMembershipProvider" />
</providers>
</membership>
</system.web>
<system.serviceModel>
<bindings>
<wsDualHttpBinding>
<binding name="wsDualHttpEndpointBinding">
<security>
<message clientCredentialType="UserName" />
</security>
</binding>
</wsDualHttpBinding>
</bindings>
<services>
<service name="MechService.MechService">
<endpoint address="localhost/MechService" binding="wsDualHttpBinding" bindingConfiguration="wsDualHttpEndpointBinding"
name="wsDualHttpEndpoint" contract="MechService.IMechService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<serviceCertificate findValue="CN=TempCert" />
<userNameAuthentication userNamePasswordValidationMode="MembershipProvider"
membershipProviderName="MySqlMembershipProvider" />
</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>
This is the function for registering new users.
public string CreateUser(String Name, String Password, String Email, String Question, String Answer)
{
MembershipCreateStatus status;
try
{
MembershipUser newUser = Membership.CreateUser(Name, Password, Email, Question, Answer, true, out status);
if (newUser == null)
{
return GetErrorMessage(status);
}
else
{
return "MECH_CODE_SUCCESS";
}
}
catch (Exception ex)
{
return ex.Message;
}
}