ASP.Net

...now browsing by category

 

Request and install client certificate – Windows 2003 server

Tuesday, September 6th, 2011

Last post was about how to request and install a server-side certificate in preparation for authenticating WCF service client using client certificate. Once the server-side certificate is in place, it’s time to get the client certificate in order. Here were the steps I took a few days ago for requesting, issuing and installing a client certificate in a Windows 2003 server machine:

  1. Went to Http://localhost:8080/CertSrv – >Request a certificate ->Browser certificate
  2. Submiited the request by following on-screen instruction (entered Name, e-mail, Company, department and chose key strength, 2048)
  3. Went into CA (Start->Administrative tools -> Certificate Authority ->Pending requests folder
  4. All tasks -> Issue and issued the client or browser certificate.
  5. Went into Issued Certificates folder and double clicked on the certificate request item ->Details – >Copy to file, the “Welcome to the Certificate Export
    wizard” pop up, Next and chose “Based-64 encoded X.509 (.Cer) option, same as the server-side cert created previously, Next
  6. Copied to c:\ClientCert.cer, Next and “Completing the Certificate Export wizard” showing “File Name, Export Keys (No), Include all certificates in the certification path (No), File format (base64-coded X.509)”, Finish
  7. Went into c:\ClientCert.cer and double clicked to open the Certificate – >Install certificate – >Next – >”Automatically select a certificate store,..” -> Next -> Finish

Install Microsoft Certificate Service

Wednesday, August 31st, 2011

I am in a project that requires me to use client certificate to authenticate web users who make request to using my WCF service hosted in a SSL secured website. During development phase, I just want to be able to test out the proof-of-concept, so I need to be able to self-request client certificates and grant them using localhost Certificate Authority (CA). The first step is to install the Microsoft Certificate Service on my local machine, a Windows 2003 Server. Here were the steps I went through to get this done:

  1. Went to Start->Control Panel -> Add/Remove Programs – > Add/Remove Windows Components
  2. Checked the “Certificate Services” and clicked Next
  3. CA Type: there was only two options enabled: “Stand-alone root CA” and “Stand-alone subordinate CA”.
    The two Enterprise level CA were grayed out probably due to that my machine is not an actual Domain Controller. I left the default option “Stand-alone root CA”
    alone and clicked Next
  4. CA Identity: I entered my machine name to the “Common name for this CA” box, and moved on.
  5. Next screen is “Certificate Database Settings” and just leave everything as it is (Certificate database:
    c:\windows\system32\CertLog, Certificate Database log: ibid, Shared folder: C:\CAConfig) and clicked on Next
  6. At this point, I was prompted with a Windows message “To complete the installation, certificate Services must temporarily stop the
    Internet Information Services. Do you want to stop the service now?”, answered Yes
  7. Well, then I ran into the screen that asked for Windows Service Pack 2 CD”, changed location to c:\I386 and it went through.
  8. Another Message box about enabling ASP on IIS popped up, clicked Yes, and the installation was completed successfully.
  9. To verify the CA is installed correctly, go Start->Administrative Tools ->Certificate Authority and the CA MMC should come up showing local machine as root and four folders named “Revoked Certificates”, “Issued Certificates”,”Pending Requests” and “Failed Requests”. In the next post, I will cover the steps I went through to submit Certificate requests that will be showing under the “Pending Requests” here

Reference: http://www.ehow.com/how_5143670_install-microsoft-certificate-services.html

Create and apply a self-signed certificate – Windows 7/IIS7

Sunday, August 7th, 2011

Creating a self-signed certificate on Windows 7/IIS7 was quite a different experience and it took me more time to set it up and work correctly (in retrospect, it should have been easier as most of things can be configured with GUI tool). Anyway, I don’t want to repeat the pain and relearn how this is done, let me summarize the steps here to share with others and to help me find it easier in a rainy day:

  1. Open IIS7 (If IIS7 is not available from Administrative tools, go to Control Panel – > Programs – > Turn Windows Features On or Off.
  2. Click on machine node then double click on “Server Certificates” on the IIS pane
  3. Select “Create self-signed certificate” from the “Action” pane and give a friendly name such as “WcfSecure” in this case.
  4. Once the server certificate is created, view the certificate detail and write down the Thumbprint, something like ae 8f b2 b4 b0 b6 07 16 8e 73 51 35 38 cd 6b bb 7e 1f 12 d5, and remove the spaces to become ae8fb2b4b0b607168e73513538cd6bbb7e1f12d5, copy it to notepad for later use.
  5. Next, configured the Certificate to port, using VS2010 Guid tool to generate a GUID and run VS2010 Command prompt (must run as admin):netsh http add sslcert ipport=0.0.0.0:8080 certhash=ae8fb2b4b0b607168e73513538cd6bbb7e1f12d5 appid={0270078A-39C3-47E8-845C-07D904672C71}
  6. Created a website to use the certificate so that WCF Service can be hosted in https mode; to do that click on Sites node and right click ->Add Web Site ->Named it “WcfDemo” and assign to Port 444 (443 and 442 have already been taken)
  7. Assign the certificate to the new website by choosing Binding type “https”, and pick the certificate from the Certificate drop down; certificate is on machine or server level, so there could be multiple certificates and multiple site can use same certificate.
  8. Refer to MSDN article at http://msdn.microsoft.com/library/ff406125.aspx for more in-depth detail.

It is important to note, that In IIS7, whenever a new website is created, it automatically creates a new application pool named the same as website, in this case, WcfDemo is the new app pool. And it automatically defaulted to use .Net Framework version 2.0, so be careful to manaully change it to the version that your Wcf app is using, in my case, changed to .net 4.0. Pay attention to Identity; by default, the Identity uses ApplicationPoolIdentity, other options are LocalService, LocalSystem, NetworkService, these are under Built-in account dropdown; you can also use Custom account and use the Windows user account for the application pool identity. If sqlexpress database is used for storing Membership users and if the security mode is set to use Integrated Security=true, then the
Application pool identity must use Localsystem or an “An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail.” error will throw when WCF client calls the Wcf Service from this website.

If, however, the sql database uses “SQL Server Authentication” mode and passes in a predefined username and password in the sql connection string, then you can leave the default ApplicationPoolIdentity alone.

Created a self-signed certificate for WCF development – Windows 2003

Tuesday, July 12th, 2011

During the development of a WCF app, I needed to issue a self-signed certificate to my local Windows 2003 server in order to test out ways to secure WCF server-client communication. For IIS6 this was a bit trickier than IIS7. I needed to download the IIS6 resource tool kit and then run selfssl.exe to create the certificate. IIS7 could do it right on its GUI. Here were the detail steps that I went through to create a SSL-enabled hosting environment (via certificate) on my local development machine (credited this very useful posting here):

  1. Downloaded IIS6 resource kit from here http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=17275 and installed it.
  2. Start ->All Programs -> IIS Resources-> SelfSSL
  3. This launched into command line:C:\Program Files\IIS Resources\SelfSSL>selfssl /N:CN=localhost:8088 /K:1024 /V:365 /S:437690215 /T
    Explanations:

    • localhost:8088 – this is where the https site is to be hosted; as port 80 already taken by another web host, I used 8088 for the new site;
    • /K: is the key size – 2048 is recommended (but 1024 worked for my case);
    • /V: days of validity – 365 is recommended (I actually used 730 or 2 years for development convenience)
    • /S: number for your web site identifier in IIS (437690215 is site id for Wcfhost, default website usually is 1, found it under the root of the website property)
    • /T makes the certificated trusted
  4. Answered “Y” at the next prompt.
  5. The message:”The self signed certificate was successfully assigned to site 437690215″
    Go back to IIS6 and now there is a Certificate under the Directory Security

For creating a self-signed certificate in IIS7, follow this article at MSDN. http://msdn.microsoft.com/library/ff406125.aspx

Smtp mail problem at Winhost (solved)

Tuesday, June 28th, 2011

When I tried to send email from my main site hosted at Winhost.com, I got this permission error: “Request for the permission of type ‘System.Net.Mail.SmtpPermission, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′ failed..”. Winhost support forum has responded to this problem and suggested adding “<trust level=”Full”> under the <system.web> in web.config. I did that and the problem went away.

Thanks to folks at winhost support forum, I was also able to call Winhost smtp client, using Network credentials given to my hosting account, directly from my development local machine and sent email out by port 587. This sample code at Winhost KB was the right place to get start with Winhost smtp mail: http://support.winhost.com/KB/a650/how-to-send-email-in-aspnet.aspx.

Moved to Winhost

Thursday, June 23rd, 2011

Finally got fed up with the slowness of WP hosting at Godaddy, I decided to move my WP blog there to winhost. Yeah, Godaddy has many features that are powerful and convenient, but that exactly was my problem with them – there are too many flashy features that crowded the site and slows down the UI experience. It was easier to install WordPress and/or other open source apps on Godaddy as they are collectively located and a few button clicks was all it needed. But once my blog was setup, browsing to it was a pain and sometimes even showed time out error.

Winhost is a million mile apart from Godaddy’s flashy world. It is simple, clean and down to earth, and the price is right too. Although at the beginning I felt frustrated for lack of custom tools but then I figured out everything I needed can be found in Forum or/and KB. I first relocated my main site yangsoft.com which is in ASP.Net 4.0 and the site is already loading 10 times faster. I have been using WordPress for my blogs since early 2010 and liked it a lot, so I wanted to transfer the old blogs from Godaddy to Winhost. The way to do it seemed to be backing up mysql db from Godaddy, download it to local drive, then use Mysql Workbench to open the sql file and execute it against the newly created mysql db on Winhost server. It seemed to be working but when I browsed to the blog.yangsoft.com at Winhost, the links on right side-bar always want to point back to my old site at Godaddy. If I cannot fix this in next day or so, I will just resolve to the old fashion way – copy and paste.

At this point, I installed WordPress from scratch to yangsoft.com/blog and the installation process was very smooth and clean. Just followed the instruction given by Winhost forum at http://forum.winhost.com/showthread.php?t=5198

Manipulate master page from content page

Thursday, April 14th, 2011

I have a admin.master master page that is shared by several content pages. On the master page, I have a set of side-bar menus that get loaded dynamically from a xml file via a WebuserControl, this part of codes look like this:

<div id="LeftSideMenu" style="height:100%;">

<uc3:SideMenuXml ID="mnuCalendar" runat="server" MenuName="Calendar" />           <uc3:SideMenuXml ID="mnuUser" runat="server" MenuName="User" />

</div>

In the SideMenuXml.ascx, codes behind load xml content properly based on the MenuName which corresponds to a segment in the xml file that looks like this:

<Sidebar>

<Calendar>

<Name>School Calendar</Name>

<Url>student/SchoolCalendar.aspx</Url>

<Description>View school calendar</Description>

<DisplayOrder>1</DisplayOrder>

<Roles>Public</Roles>

</Calendar>

</Sidebar>

This has been working great, but sometimes I want a different set of side menus loaded into admin.master based on the purpose of the content page. Today, I learned that this can be accomplished by these steps:

  1. Create a public property in the master page, named “PageType” or whatever
  2. To access this property of master page, I needed to add this attribute to the content page, <%@ MasterType VirtualPath=”~/Admin.master” %>
  3. Then on the Page_Init event of my content page, I set this property to an enum value I wanted: protected void Page_Init(object sender, EventArgs e)    {        Master.PageType = MasterPageTypes.Contest;
    }
  4. Then on the admin.master I added this line of server-client-mixed code:
    <div id="LeftSideMenu" style="height:100%;">
    <% if (PageType== MasterPageTypes.Contest) {%>
    <uc3:SideMenuXml ID="mnuContest" runat="server" MenuName="Contest" />
    <% } %>

With that, I accomplished the goal of showing certain Contest related side menu for those content pages that set the PageType property of admin.master master page.

To sum it up, public property of master page is not accessible from its content page until you add this MasterType directive to the content page that uses the master: <%@ MasterType VirtualPath=”~/Admin.master” %>

Consume WCF service from .Net 1.1

Sunday, January 2nd, 2011

I have struggled for the past week not being able to consume a ASMX service exposed through a WCF service app that was created on .Net 4.0 and Entity Framework. The key to make a WCF service consumable by legacy .Net app was to expose the service as an old fashion ASMX, through adding a XmlSerializerFormat attribute while building the ServiceContract interface, as shown in this sample:

[ServiceContract, XmlSerializerFormat]

public interface IService1

{

[OperationContract]

string GetData(int value);

 

[OperationContract]

CompositeType GetDataUsingDataContract(CompositeType composite);

 

}

 

The second key step was to make sure the web.config of the WCF service project would use “basicHttpBinding” and set endpoint address to “basic” type. When I first started out, many cited the reference from MSDN at http://msdn.microsoft.com/en-us/library/ms751433.aspx; I followed the example, and still got the “Underneath connection had been closed” error. Today, I came across another posting at http://social.msdn.microsoft.com/forums/en-US/wcf/thread/1f8c7fe9-784c-4beb-8d0f-060bf8bfc24f and that had liberated me from wondering why this damn thing not working – well, the web.config example in the MSDN article had an empty string in the address field while this social.msdn positing had a “basic” in the enpoint address;  I tried that and it worked this time! Thanks Jay R. Wren who answered a user’s question at social.msdn.com.

 

Here was the endpoint configuration that worked on my case:

<service name=”WcfService1.Service1″  behaviorConfiguration=”AsmxBehavior”>

<endpoint address=”basic” binding=”basicHttpBinding” contract=”WcfService1.IService1″></endpoint>

 

The entire web.config file that is in the WCF app project that will generate the ASMX service to be consumed by .Net 1.1 client is as below:

<?xml version=”1.0″?>

<configuration>

<system.web>

<compilation debug=”true” targetFramework=”4.0″ />

</system.web>

<system.serviceModel>

<services>

<service name=”WcfService1.Service1″  behaviorConfiguration=”AsmxBehavior”>

<endpoint address=”basic” binding=”basicHttpBinding” contract=”WcfService1.IService1″></endpoint>

</service>

</services>

<behaviors>

<serviceBehaviors>

<behavior name=”AsmxBehavior”>

<!– To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment –>

<serviceMetadata httpGetEnabled=”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>

<serviceHostingEnvironment multipleSiteBindingsEnabled=”true” />

</system.serviceModel>

<system.webServer>

<modules runAllManagedModulesForAllRequests=”true”/>

</system.webServer>

 

</configuration>

 

Use Session in Generic Handler file (.ashx)

Sunday, December 12th, 2010

Using Generic Handler or .ashx file instead of heavyset web form (.aspx) is a lighter-weight and faster way to handle certain types of Http request, such as rendering an large image, spit out text files, etc. I recently used it in one web project that needed to setup a Http listener to process incoming requests and not doing any Html rendering.

By default, an .ashx file (Generic Handler template from VS2010) code behind automatically added these namespaces only:

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

 

Then when I tried to store a session_id from incoming Http request’s querystring in the Session object of HttpContext.Current, and it failed. As it turned out, in order to access Session object, I needed to add a SessionState namespace, System.web.SessionState; and then implement the IRequiresSessionState interface. the beginning of the .ashx code behind now looked like this:

 

 

public class ServeRequest : IHttpHandler, IRequiresSessionState

{

 

public void ProcessRequest(HttpContext context)

{

 

//codes to handle Http request

}

}

 

 

 

Mysterious connection error in WCF web service call

Thursday, October 14th, 2010

While working on a WCF Service call to return an e-commerce order object to a web client , I sometimes got this puzzling error inside client code:

“The underlying connection was closed: The connection was closed unexpectedly.”

At the beginning, I thought this must be something to do with Entity connection or some SQL to Entity operations inside the data tier that was built on ASP.Net Entity Framework; but there was nothing to be found there.

Then I searched and visited many web postings, and most of them pointed to configuration problem with WCF service model’s endpoint settings. I even followed some postings and made the corresponding changes; but this dreaded error still lingered. I was about to give up before I realized that the WCF service call was working fine before I added couple of enumerated class members to the DataContract class that is to return. Here was the class that was built into my WCF services layer and to be returned to client when the service method “GetOrder” was called:

 

[DataContract] public class EcommOrder : SalesOrder

{

[DataMember] public int EcommOrderID { get; set; }

[DataMember] public int EcommOrderTypeID { get; set; }

// … more data members

}

//web service method call

public EcommOrder GetOrder(int orerid)

{

EcommOrder returned=new EcommOrder();

//retrieve order from data tier (EF) and populate the object

return returned;

}

On the client side where the service was invoked, the serializable object EcommOrder was fetched good and sound.  Then I added this enum member to the EcommOrder class inside the Service tier:

[DataContract] public enum OrderTypes

{

[EnumMember]

StudentOrder=1,

[EnumMember]

CorporateOrder=2,

//and so on

 

}  and EcommOrder now looks like :

 

[DataContract] public class EcommOrder : SalesOrder

{

[DataMember] public int EcommOrderID { get; set; }

[DataMember] public int EcommOrderTypeID { get; set; }

[DataMember] public OrderTypes EcommOrderType;

// … more data members

}

Then I went back to the client code and call the same service call to return the modified EcommOrder object: Oops, now I got that dreaded and misleading error:

“The underlying connection was closed: The connection was closed unexpectedly.”

To confirm the Enum was the cause, I went back and took out the EcommOrderType enumerated member, then re-called the service, yes, the error again went away.

How wacky was that?