Implemeneting IIS hosted WCF service with AzMan role provider - asp.net

I try to implement a WCF service that is hosted on IIS, the users ask for some templates files transformation and it return them the processed file (If they are authorized for the template they asked for).
I selected the visual studio project template "WCF Service Application" and got a project with aspNetCompatibilityEnabled set to true etc.
I thought on implementing my need using AzMan authorization since I am fimiliar with that mechanism and did similiar things with it.
However, I can't debug the service since I get 401 unauthorized.
I assume the user token is not being sent.
1. How can I enable Azman usage for WCF, IIS hosted service?
2. Is there similiar mechanism embedded in WCF that can assist checking if a user belongs to a group that allowed to access some site folder?
Confiuration:
<configuration>
<connectionStrings>
<add name="LocalPolicyStore"connectionString="msxml://c:/RolesData/azmanstore.xml" /> </connectionStrings>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
<authentication mode="Windows" />
<authorization>
<deny users="?" />
</authorization>
<roleManager enabled="true" cacheRolesInCookie="true" defaultProvider="RoleManagerAzManProvider" cookieName=".ASPXROLES" cookiePath="/" cookieTimeout="30" cookieRequireSSL="true" cookieSlidingExpiration="true" createPersistentCookie="false" cookieProtection="All">
<providers>
<add name="RoleManagerAzManProvider" type="System.Web.Security.AuthorizationStoreRoleProvider, System.Web, Version=4.0.0.0, Culture=neutral, publicKeyToken=b03f5f7f11d50a3a" connectionStringName="LocalPolicyStore" applicationName="DRP" />
</providers>
</roleManager>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="metadataBehavior">
<!-- 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"/>
<serviceAuthorization principalPermissionMode="UseAspNetRoles"
roleProviderName="RoleManagerAzManProvider" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="ExcelGeneratingService.ExcelGeneratorService" behaviorConfiguration="metadataBehavior">
<endpoint
address=""
binding="basicHttpBinding" bindingConfiguration="excelGeneratorServiceBinding"
contract="ExcelGeneratingService.IExcelGeneratorService"/>
<endpoint
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="excelGeneratorServiceBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<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>
Code:
//Check if the user is allowed to access this path
if (!UrlAuthorizationModule.CheckUrlAccessForPrincipal(virtPath, user, "GET"))
{
return false;
}

I have solved it. I hope it will help someone.
Some fixes to the configuration (Attached). All users allowed but filtered at lower level folders.
Installing missing authorization handlers at the IIS on the OS (Turn windows features on...)
Use the local IIS and not IIS Express from the visual studio
Clean the IIS Express configurations at the user data folder (C:\Users\\Documents\IISExpress\config) if the IIS visrtual folder creation fails
Give my azman store a reader security privilege (at the azman console) for the service application pool user (from the IIS).
Configuration:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<connectionStrings>
<add name="LocalPolicyStore" connectionString="msxml://c:/RolesData/ExcelGeneration.xml" />
</connectionStrings>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<authentication mode="Windows" />
<authorization>
<allow users="*" />
</authorization>
<identity impersonate="false" />
<roleManager enabled="true" cacheRolesInCookie="true" defaultProvider="RoleManagerAzManProvider" cookieName=".ASPXROLES" cookiePath="/" cookieTimeout="30" cookieRequireSSL="true" cookieSlidingExpiration="true" createPersistentCookie="false" cookieProtection="All">
<providers>
<add name="RoleManagerAzManProvider" type="System.Web.Security.AuthorizationStoreRoleProvider, System.Web, Version=4.0.0.0, Culture=neutral, publicKeyToken=b03f5f7f11d50a3a" connectionStringName="LocalPolicyStore" applicationName="ExcelGeneration" />
</providers>
</roleManager>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="metadataBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceAuthorization principalPermissionMode="UseAspNetRoles"
roleProviderName="RoleManagerAzManProvider" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="ExcelGeneratingService.ExcelGeneratorService" behaviorConfiguration="metadataBehavior">
<endpoint address="" bindingConfiguration="excelGeneratorServiceBinding" binding="basicHttpBinding" contract="ExcelGeneratingService.IExcelGeneratorService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="excelGeneratorServiceBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<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>

Related

WCF Web Deploy HTTP Error 404 - Not Found

I have created a REST WCF web service in vb.net and published it to 1&1 Host Server using Web Deploy. When trying to call one of the services, I keep receiving:
HTTP Error 404 - Not Found.
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
I have looked at the wwwroot directory and I can find the .svc files and web.config, so I can't figure out why it can not find it. The call I am making is: http://localhost/Service1.svc/GetTimesheetDetails/1/1/11256/2017-8-9
<OperationContract()>
<WebInvoke(Method:="GET", ResponseFormat:=WebMessageFormat.Json, BodyStyle:=WebMessageBodyStyle.Wrapped, UriTemplate:="GetTimesheetDetails/{userid}/{organisationid}/{jobid}/{sdate}")>
Function GetTimesheetDetails(ByVal userid As String, ByVal organisationid As String, ByVal jobid As String, ByVal sdate As String) As List(Of JobEngineerTime)
I have tested these calls running them on Visual Studio and it works fine, unfortunately I am unable to get it to run through the 1&1 server.
This is my web.config:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<!--Disabled custom errors to allow display of detailed errors.-->
<!--<customErrors mode="Off"/>-->
<customErrors mode="RemoteOnly" defaultRedirect="~/Errors/500.htm">
<error statusCode="404" redirect="~/Errors/404.htm"/>
</customErrors>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="webBehaviour">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="metadataBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="metadataBehavior" name="WCFTimesheetWebService.Service1">
<endpoint address="" behaviorConfiguration="webBehaviour"
binding="webHttpBinding" contract="WCFTimesheetWebService.IService1" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
<service behaviorConfiguration="metadataBehavior" name="WCFTimesheetWebService.Service2">
<endpoint address="" behaviorConfiguration="webBehaviour"
binding="webHttpBinding" contract="WCFTimesheetWebService.IService2" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
<service behaviorConfiguration="metadataBehavior" name="WCFTimesheetWebService.Service3">
<endpoint address="" behaviorConfiguration="webBehaviour"
binding="webHttpBinding" contract="WCFTimesheetWebService.IService3" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<!-- Allowing Cross-Origin Resource Sharing (CORS) - The httpProtocol settings allow web services to be called from external domains using JavaScript-->
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type, Accept" />
</customHeaders>
</httpProtocol>
<modules runAllManagedModulesForAllRequests="true"/>
<httpErrors errorMode="Detailed" />
<validation validateIntegratedModeConfiguration="false"/>
<!--
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>
A couple of mappings were missing in IIS "Handler Mappings". To sort out the problem, all I had to do was click on "Revert to Parent" inside "Handler Mappings" which restored the missing mappings and it started working.

WCF Service wsHttpBinding

I'm getting error while creating wcf service using wsHtpBinding help page is getting error and services also not working
Help Page Error:
The resource cannot be found. Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
http://localhost:80/Service1.svc/help
My old working wsHttpbinding project web.config but it's not working now:
web.config
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" executionTimeout="3600" maxRequestLength="10000000"/>
<customErrors mode="Off" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceTypeBehaviors">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding >
<binding name="MyBasicwsHttpBinding">
<security mode="None">
<transport clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="MyServiceTypeBehaviors" name="WcfService1.Service1">
<endpoint address="mex" binding="wsHttpBinding" bindingConfiguration="MyBasicwsHttpBinding" name="WcfService1.Service1" contract="WcfService1.IService1"/>
</service>
</services>
<serviceHostingEnvironment minFreeMemoryPercentageToActivateService="0" aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
In my case, I found out that a Microsoft IIS filtering module Url Scan 3.1 was installed on IIS/website, which have it's own limit to reject incoming requests based on content size and return "404 Not found page".
It's limit can be updated in %windir%\System32\inetsrv\urlscan\UrlScan.ini file by setting MaxAllowedContentLength to the required value.
For eg. following will allow upto 300 mb requests
MaxAllowedContentLength=314572800

WCF is showing development machine path on production server

I have deployed a wcf service app which I made on vs 2013, I published the project to a file system and moved the published version on production server. Now when I am accessing the service from production server it tries to connect to the local development machine where it says an exception
The server encountered an error processing the request. The exception message is 'Unable to connect to the remote server'.
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<!--
For a description of web.config changes see http://go.microsoft.com/fwlink/?LinkId=235367.
The following attributes can be set on the <httpRuntime> tag.
<system.Web>
<httpRuntime targetFramework="4.5" />
</system.Web>
-->
<system.web>
<compilation targetFramework="4.5"/>
<httpRuntime/>
<pages controlRenderingCompatibilityVersion="4.0"/>
<customErrors mode="Off"/>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*"/>
<add name="Access-Control-Allow-Headers" value="Content-Type, x-requested-with, origin, authorization, accept, client-security, X-PINGOTHER"/>
<add name="Access-Control-Allow-Methods" value="GET, PUT, OPTIONS "/>
<add name="Access-Control-Max-Age" value="3600"/>
<add name="Access-Control-Allow-Credentials" value="true"/>
<add name="Access-Control-Expose-Headers" value="DAV, content-length, Allow"/>
</customHeaders>
</httpProtocol>
</system.webServer>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="EndpBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="ServiceBehavior" name="ServiceWebApp.Service1">
<endpoint address="" binding="webHttpBinding" contract="ServiceWebApp.IService1" behaviorConfiguration="EndpBehavior" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="secureHttpBinding">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</webHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true"/>
<standardEndpoints>
<webScriptEndpoint>
<standardEndpoint crossDomainScriptAccessEnabled="true"/>
</webScriptEndpoint>
</standardEndpoints>
</system.serviceModel>
</configuration>

Using PrincipalPermissionAttribute with Custom role provider

I'm working on a new security infrastracture for my organization. Since we develop systems for the inside organization use I'd like to use Windows Authentication, but for the authorization we manage a separate Oracle DB (for historical reasons). My idea was to use PrincipalPermissionAttribute defining
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
in Global::Application_Start
and
<system.web>
<compilation debug="true" targetFramework="4.0" />
<authorization>
<deny users="?"/>
</authorization>
<roleManager **defaultProvider="MyRoleProvider"**
enabled="true"
cacheRolesInCookie="true"
cookieName=".ASPROLES"
cookieTimeout="30"
cookiePath="/"
cookieRequireSSL="false"
cookieSlidingExpiration="true"
cookieProtection="All" >
<providers>
<clear />
<add
name="MyRoleProvider"
type="WcfServiceLibrary1.MyRoleProvider"
connectionStringName="Service1"
applicationName="InfraTest"
writeExceptionsToEventLog="true" />
</providers>
</roleManager>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpEndpointBinding">
<security mode="TransportCredentialOnly">
<transport **clientCredentialType="Windows"** />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="WcfService1.Service1">
<endpoint address="WcfAuthenticationTest" binding="basicHttpBinding"
bindingConfiguration="BasicHttpEndpointBinding" name="BasicHttpEndpoint"
contract="WcfService1.IService1">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost/WcfAuthentication"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceAuthorization **principalPermissionMode="UseAspNetRoles"**/>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
in my Web.config using my custom role provider that should access the Oracle DB to check the role. But I can not make it work. Is there any way to make the PrincipalPermissionAttribute work in this way or may be the entire concept is wrong? I thought of implementing my custom CodeAccessSecurityAttribute but it is not that simple so I prefer not to do it
Does anybody have any idea of the issue? I'll be glad to get some answers
There are two things that I've learned lately. First af all my concept was right, I can use PrinciplePermissionAttribute with costom role provider, the second is that I was totaly confused with the web.config tags. tag is used for the asp .net settings, while is used for WCF settings. So a liitle bit configuration solved the entire problem. Here is the right configuration
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" defaultLanguage="c#" targetFramework="4.0" />
<roleManager enabled="true" cacheRolesInCookie="true" cookieName=".ASPROLES"
defaultProvider="MyRoleProvider">
<providers>
<clear />
<add connectionStringName="Service1" applicationName="InfraTest"
writeExceptionsToEventLog="false" name="MyRoleProvider" type="SecLib.MyRoleProvider" />
</providers>
</roleManager>
</system.web>
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBindingConfiguration" closeTimeout="00:01:00"
sendTimeout="00:10:00" maxBufferSize="524288" maxReceivedMessageSize="524288">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="WcfRoleProviderTestService.Service1"
behaviorConfiguration="BasicHttpServiceBehavior" >
<endpoint name="BasicHttpEndpoint"
contract="WcfRoleProviderTestService.IService1"
address="WcfAuthenticationTest"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBindingConfiguration" />
<host>
<baseAddresses>
<add baseAddress="http://localhost/WcfRoleProviderTestService/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="BasicHttpServiceBehavior">
<serviceAuthorization principalPermissionMode="UseAspNetRoles"
roleProviderName="MyRoleProvider" impersonateCallerForAllOperations="true" />
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
You need not include impersonateCallerForAllOperations="true" unless you need impersonation

ASP.NET Membership Provider authentication not working authenticating WCF Service

I have a SqlMembershipProvider store with Roles enabled. This is configured and has the user "devtest" in the roles "xxUser" and "xxAdmin".
I also have a WCF service, which I want to authenticate and authorize against. My problem is that:
the authorisation is not
happening, code just executes
despite the policy attribute
I don't get any identity or security
context so do not know who is
calling the service
I need:
to know which user is calling the
method
some degree of rejecting
users if permissions don't match up
(ideally this should be performed
within the
RoleProvider/MembershipProvider/WCF
but can do it myself if I have to)
SSL in transport
I have my service contract set up thus:
[ServiceContract]
public interface ISupportService
{
[OperationContract]
[PrincipalPermission(SecurityAction.Demand, Role = "ThisRoleDoesNotExist")]
List<BaseInterestRate> GetAllBaseInterestRates();
}
the code is simple enough:
public class SupportService : ISupportService
{
public List<BaseInterestRate> GetAllBaseInterestRates()
{
OperationContext operationContext = OperationContext.Current;
ServiceSecurityContext serviceSecurityContext = ServiceSecurityContext.Current; // is always null
using (xxxEntities entities = new xxxEntities())
{
return new List<BaseInterestRate>(entities.BaseInterestRates);
}
}}
My service configuration is thus:
-->
<behaviors>
<serviceBehaviors>
<behavior name="SupportServiceBehavior">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="AspNetSqlRoleProvider" />
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="MembershipProvider"
membershipProviderName="SqlMembershipProvider" />
</serviceCredentials>
</behavior>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
Having already configured the MembershipProvider:
<membership defaultProvider="SqlMembershipProvider" >
<providers>
<clear/>
<add name="SqlMembershipProvider"
connectionStringName="SqlMembershipProvider"
applicationName="xxx"
type="System.Web.Security.SqlMembershipProvider" />
</providers>
</membership>
<roleManager enabled="true">
<providers>
<clear />
<add connectionStringName="SqlMembershipProvider" applicationName="xxx"
name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" />
<add applicationName="xxx" name="AspNetWindowsTokenRoleProvider"
type="System.Web.Security.WindowsTokenRoleProvider" />
</providers>
</roleManager>
I have followed the instructions at these pages to the letter:
How to: Use the SQL Server Role Provider with Windows Authentication in WCF Calling from Windows Forms (MSDN)
How to: Create and Install Temporary Client Certificates in WCF During Development (MSDN)
How to: Use wsHttpBinding with Username Authentication and TransportWithMessageCredentials in WCF Calling from Windows Forms (MSDN)
Also quite useful found via SO: Use Asp.Net Membership provider with a WCF .svc service (Alkampfer's Place)
I would at lest expect an issue with certificates/transport/etc. to fail with exceptions, but I can debug right in and over the WCF call. I have no security context/ user context available to me and when I use a user not in the two mentioned roles (which I do in the code example above), I don't get "kicked out".
My client app is currently a Web App, but will ultimately also serve a Windows Forms app and Test suite. I'm currently using the ASP.NET WebDev server and am running .NET 4.0.
Am I missing something?
I'm a little new to WCF Rest services, but during my own testing I ran into a similar problem to this. I came across this video, which helped a bit (even if it wasn't quite what I was trying to do):
http://channel9.msdn.com/blogs/rojacobs/endpointtv-securing-restful-services-with-aspnet-membership
Essentially the problem was that under the asp.net configuration I had to disable anonymous access in order for it to use the MembershipProvider authentication:
system.web>
<authorization>
<deny users="?" />
</authorization>
...
I don't think you can set the principal permission on the interface.
I bet if you move it onto the service implementation method it will work
or at least start breaking for a different reason (I am currently stuck at that point - I get access denied exceptions - hopefully you dont!)
(I first tried to put them on the contract interface also)
this is the correct configuration for wcf service self-hosted with SSL:
<?xml version="1.0"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<connectionStrings>
<add name="mySqlConnection" connectionString="Data Source=.\SQLEXPRESS2012;Integrated Security=SSPI;Initial Catalog=aspnetdb;"/>
</connectionStrings>
<system.web>
<compilation debug="true"/>
<!-- Configure the Sql Membership Provider -->
<membership defaultProvider="MySqlMembershipProvider" userIsOnlineTimeWindow="15">
<providers>
<clear/>
<add name="MySqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="mySqlConnection" applicationName="UsersManagementNavigationApplication" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" passwordFormat="Hashed"/>
</providers>
</membership>
<!-- Configure the Sql Role Provider -->
<roleManager enabled="true" defaultProvider="MySqlRoleProvider">
<providers>
<clear/>
<add name="MySqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="mySqlConnection" applicationName="UsersManagementNavigationApplication"/>
</providers>
</roleManager>
</system.web>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webBinding">
<security mode="Transport">
<transport clientCredentialType="Basic"/>
</security>
</binding>
</webHttpBinding>
<basicHttpBinding>
<binding name="basicBindingConfiguration">
<security mode="Transport">
<transport clientCredentialType="Basic"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="webEndpointBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="webServiceBehavior">
<serviceMetadata httpsGetEnabled="true"/>
<serviceThrottling/>
<serviceDebug/>
</behavior>
<behavior name="myServiceBehavior">
<!-- Configure role based authorization to use the Role Provider -->
<serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="MySqlRoleProvider">
</serviceAuthorization>
<serviceCredentials>
<!-- Configure user name authentication to use the Membership Provider -->
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfServiceHTTPSSelfHosted.MyCustomValidator, WcfServiceHTTPSSelfHosted" />
</serviceCredentials>
<!-- To avoid disclosing metadata information, set the value below to false before deployment -->
<serviceMetadata 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"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="myServiceBehavior" name="WcfServiceHTTPSSelfHosted.WcfServiceHTTPSSelfHosted">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicBindingConfiguration" contract="WcfServiceHTTPSSelfHosted.IWcfServiceHTTPSSelfHosted"/>
<endpoint address="web" behaviorConfiguration="webEndpointBehavior" binding="webHttpBinding" bindingConfiguration="webBinding" contract="WcfServiceHTTPSSelfHosted.IWcfServiceHTTPSSelfHosted"/>
<endpoint address="mex" binding="mexHttpsBinding" bindingConfiguration="" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="https://localhost:50001/WcfServiceHTTPSSelfHosted/"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
if you want more info take a look this:
http://www.albertoschiassi.it/Home/tabid/55/EntryId/94/Use-ASP-NET-SqlMemberShipProvider-in-WCF-self-hosted-service.aspx
and
http://www.albertoschiassi.it/Home/tabid/55/EntryId/95/Use-ASP-NET-SqlMemberShipProvider-in-WCF-self-hosted-service-with-SSL.aspx

Resources