Configuring Log4Net For Web Applications/Services

We all understand why we should use configuration files for log4net. The use of configuration files is specified @ http://logging.apache.org/log4net/release/manual/configuration.html. The config settings can either be added to the web.config file or we can create a seperate xml file say log4net.config.
I prefer to use a seperate config file. And the main reason is log4net framework will watch (using FileSystemWatcher) the external configuration file and will reload the config each time the file is modified. For some reason this powerful feature is not available if the settings are kept in web.config.
The other important class to understand is XmlConfigurator. This configurator must be set if a config file is used.
The default way to configure is log4net.Config.XmlConfigurator.Configure();
This makes the log4net look into the app.config or web.config file.
Configuration Attributes… read at the link specified
XmlConfiguratorAttribute The log4net.Config.XmlConfiguratorAttribute Allows the XmlConfigurator to be configured using the following properties:

  • ConfigFile If specified, this is the filename of the configuration file to use with the XmlConfigurator. This file path is relative to the application base directory (AppDomain.CurrentDomain.BaseDirectory). This property cannot be used in conjunction with the ConfigFileExtension property.
  • ConfigFileExtension If specified, this is the extension for the configuration file. The assembly file name is used as the base name with the this extension appended. For example if the assembly is loaded from the a file TestApp.exe and the ConfigFileExtension property is set to log4net then the configuration file name is TestApp.exe.log4net. This is equivalent to setting the ConfigFile property to TestApp.exe.log4net. The path to the configuration file is build by using the application base directory (AppDomain.CurrentDomain.BaseDirectory), the assembly file name and the configuration file extension.  This property cannot be used in conjunction with the ConfigFile property.
  • Watch If this flag is specified and set to true then the framework will watch the configuration file and will reload the config each time the file is modified.

If neither of the ConfigFile or ConfigFileExtension properties are specified, the web configuration file (web.config) will be used as the log4net configuration file. The System.Configuration API is only available if the configuration data is in the application’s config file; The file named MyApp.exe.config or Web.config.
Because the System.Configuration API does not support reloading of the config file the configuration settings cannot be watched using the log4net.Config.XmlConfigurator.ConfigureAndWatch methods. The main advantage of using the System.Configuration APIs to read the configuration data is that it requires less permissions than accessing the configuration file directly. The only way to configure an application using the System.Configuration APIs is to call the log4net.Config.XmlConfigurator.Configure() method or
the log4net.Config.XmlConfigurator.Configure(ILoggerRepository) method.

All that said let’s have a look how to put all this in place.

  1. Create a log4net.config file. This file will contain your logger settings. Please refer the official website for details how to create a valid config file. http://logging.apache.org/log4net
  2. Add the following attribute to your AssemblyInfo.cs file
    [assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
    Alternately you can add the following line of code in the global.asax file in Application_Start Event.
    XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(HttpContext.Current.Request.PhysicalApplicationPath + “log4net.config”));
  3. Create the Logger
    private static readonly ILog log = LogManager.GetLogger(typeof(NameofYourClass));

    Its a good practice of create a seperate logger for each class. Then you can scope where the error occurred.
  4. Start logging.
    log.Error(exception.Message, exception.InnerException);

How to create a wsdl file

The simplest option is to navigate to the web service url in the browser and add a querystring parameter wsdl to it.
example: http://localhost:1831/Service1.asmx?wsdl
And the wsdl will be emitted on the browser.
The other way is to use the disco.exe utility.
example: disco /o:C:\outputdir http://localhost:1831/Service1.asmx
to run disco open the visual studio command prompt.
the syntax is disco.exe options urlToDiscover
/o or /out specifies the output directory to save the discovered documents in. The default is the current directory.

string.Format

I love the string.Format method available in .Net
Some of the the formatting options that are available have been described in this post. Padding / alignment formatting options are the most handy. These options are also available to every argument, regardless of type.

example output
String.Format(“–{0,10}–”, “test”); –      test–
String.Format(“–{0,-10}–”, “test”); –test      –

Number formatting is culture dependant. For example, formatting a currency string on a system with regional settings to UK will return a result like £9.99, formatting a currency on a machine set for the US region would return $9.99.

specifier type format output(double 1.2345) output(int -12345)
c currency {0:c} £1.23 -£12,345.00
d decimal(whole number) {0:d} System.FormatException -12345
e exponent / scientific {0:e} 1.234500e+000 -1.234500e+004
f fixed point {0:f} 1.23 -12345.00
g general {0:g} 1.2345 -12345
n number {0:n} 1.23 -12,345.00
r round trippable {0:r} 1.23 System.FormatException
x hexadecimal {0:x4} System.FormatException ffffcfc7

 

custom number formatting

specifier type format output(double 1234.56)
0 zero placeholder {0:00.000} 1234.560
# digit placeholder {0:#.##} 1234.56
. decimal point placeholder {0:0.0} 1234.6
, thousand separator {0:0,0} 1,235
% percentage {0:0%} 123456%

In addition there is the group separator; this is useful for varying the format, depending on the value of the parameter passed. For example

String.Format("{0:£#,##0.00;(£#,##0.00);Nothing}", value);

This will output “£1,240.00″ if passed 1243.56.  It will output the same format bracketed if the value is negative “(£1,240.00)”, and will output the string “Nothing” if the number is zero.

date formatting

Date formats are very dependant on the culture information passed. The examples below are shown using the UK culture.

specifier type output(June 8, 1970 12:30:59)
d Short Date 08/06/1970
D Long Date 08 June 1970
t Short Time 12:30
T Long Time 12:30:59
f Full date and time 08 June 1970 12:30
F Full date and time (long) 08 June 1970 12:30:59
g Default date and time 08/06/1970 12:30
G Default date and time (long) 08/06/1970 12:30:59
M Day / Month 8 June
r RFC1123 date string Mon, 08 Jun 1970 12:30:59 GMT
s Sortable date/time 1970-06-08T12:30:59
u Universal time, local timezone 1970-06-08 12:30:59Z
Y Month / Year June 1970

 

custom date formatting

specifier type output(June 8, 1970 12:30:59)
dd Day 08
ddd Short Day Name Mon
dddd Full Day Name Monday
hh 2 digit hour 12
HH 2 digit hour (24 hour) 12
mm 2 digit minute 30
MM Month 06
MMM Short Month name Jun
MMMM Month name June
ss seconds 59
tt AM/PM PM
yy 2 digit year 70
yyyy 4 digit year 1970
: seperator, e.g. {0:hh:mm:ss} 12:30:59
/ seperator, e.g. {0:dd/MM/yyyy} 08/06/1970

There are others, including time zone formatting and so on, but the ones above are the most commonly used.

 

Session Management with a single sign on server

  1. Designing it with 
  2. CAS – Central Authentication server
  3. It needs to have three components
    • login url
    • authentication url
    • logout url
  4. All the systems needs to have a login link, where the users can enter their credentials
  5. The systems needs to call on every single request an authentication url, which will return true or false indicating that the user has been authenticated
  6. The CAS needs to do the session idle timeout. As soon as the request is answered the idle timeout is refreshed
  7. The logout URL logs the user out of all the systems.
  8. The CAS shall send a cookie with a ticket for authentication, and then all systems must send this ticket back to CAS. The purpose of the cookie is automatic re authentication. This cookie must not be a persistent cookie, i.e. it expires as soon as the user closes the browser. Also called in-memory cookie
  9. It is with help of this cookie that CAS will achieve single sign on across multiple applications without prompting the user to enter the log in details again and again. Without the cookie the user enters the username and password again and again, whenever he is redirected to CAS.
  10. The cookie expire time is reset whenever it is send back to the server. And hence the session is maintained for 20 minutes or so. As soon as the cookie is expired the session is timed out. This will take care of the inactivity timeouts.
  11. When CAS receives the authentication ticket through the validation URL, it checks to see in its internal database if it issued this ticket in the past.

How to mark Session Cookie Secure

In one of my previous posts I discussed why we need to mark the cookies as secured. It becomes quite essential to mark the forms authentication cookie and the session cookie as Secured because they contain user sensitive information. A quick solution to mark the ASP.Net session cookie (by default asp.net_sessionid) and the Forms authentication cookie (by default .ASPXAUTH) is to write the following code in your EndRequest Event handler. This code can be added in an HttpModule or in your global.asax file.

// this code will mark the forms authentication cookie and the
// session cookie as Secure.
if (Response.Cookies.Count > 0)
{
    foreach (string s in Response.Cookies.AllKeys)
    {
        if (s == FormsAuthentication.FormsCookieName || s.ToLower() == “asp.net_sessionid”)
        {
             Response.Cookies[s].Secure = true;
        }
    }
}

Forms Authentication cookie can also be marked secured by setting the requireSSL attribute in the tag in the web configuration file.

One key this to note is if the server has not been setup for SSL and this logic is used, a new session will be generated for each request. Be sure to use this code only when the HTTPS is used on web server.

This posting is provided “AS IS” with no warranties, and confers no rights.

Are stored procedures safe against SQL injection?

To understand why use stored procedures in your application, refer this great article. One of the benefits of using stor procs is preventing SQL Injections. There is a nice article on wiki explaining what SQL Injection is. The first part of this post talks about how parameterized queries and stored procedures can help prevent sql injections. the second part will critically analyse whether so acclaimed stored procedures do prevent sql injections.Dynamic SQL query i.e. sql strings embedded in the code, which are formed without properly validating the user inputs are almost 100% vulnerable to SQL injection attacks. Examine this code fragment -

string username = Textbox1.Text;

string query = “SELECT [name], [address] FROM USERS  WHERE [username] = ‘” + username + “‘”;

This code is expected to fetch the user details, based on username. It can be a typical code listed on user maintainence screen. Now a malicious user can input in the textbox badguy’;DROP TABLE USERS; SELECT * FROM Countries WHERE name LIKE ‘%
This input renders the final SQL statement as follows:

SELECT [name], [address] FROM USERS  WHERE [username] = ‘badguy’;DROP TABLE USERS; SELECT * FROM Countries WHERE name LIKE ‘%’

We can see how a simple harmless query can result in big threat to your database. Parameterized stored procedures can go a long way in protecting your database applications from SQL Injection. Given no input validation, the parameterized stored procedure still does not allow you to gain access to the site.
But sometimes badly written stored procedures do not prevent injections. The important thing to do is use parameters with stored procedures. SQL injection is possible if the dynamic SQL inside the stored procedure is not handled properly. Let us see an example. 
 

CREATE PROCEDURE sp_getUser

@username varchar(200) = NULL AS

DECLARE @sql nvarchar(4000)

SELECT @sql = ‘ SELECT [name], [address] ‘ + ‘ FROM [USERS] Where [username] = ”’ + @username  + ””

EXEC (@sql)

In the above case, the variable @username is directly taken from the user input and concatenated with the string i.e. @sql. The EXEC function is being used which takes string as parameter to execute the SQL statements. Making this stored procedure vulnerable to SQL injections even though the user inputs are passed to it as parameters. The user input is enclosed in the single quotes and concatenated to a string to form SQL query. The problem lies here. Instead of the parameter being a search string to the SQL query, the user input has become the part of the query as it is enclosed inside the single quotes. If the user enters the values as badguy’;DROP TABLE USERS; SELECT * FROM Countries WHERE name LIKE ‘% then the final SQL query executed at the server will be

SELECT [name], [address] FROM [USERS] Where [username] = ‘badguy’;DROP TABLE USERS;  SELECT * FROM Countries WHERE name LIKE ‘%’

The user gets no benefit of the parameterised sql. The safer way to execute a dynamic sql in the stored procedure is

CREATE PROCEDURE sp_getUser

@username varchar(200) = NULL

AS

DECLARE @sql nvarchar(4000)

SELECT @sql = ‘ SELECT [name], [address] ‘ + FROM [USERS] Where [username] = ‘

SELECT @sql = @sql + ‘ [username] LIKE @username’

EXEC sp_executesql @sql, N‘@username varchar(200)’, @username

Why is this stored procedure different and safer from the previous one?

  1. The user input is not enclosed inside the single quotes. It is rather being passed as parameter to the SQL statement.
  2. The function sp_executesql is being used to execute with the parameter list and the parameterized SQL statements.

Measures to avoid SQL injection

  1. Validate all input coming from the user on the server.
  2. Avoid the use of dynamic SQL queries if there an alternate method is available.
  3. Use parameterized stored procedure with embedded parameters.
  4. Execute stored procedures using a safe interface such as Callable statements in JDBC or CommandObject in ADO.
  5. Use a low privileged account to run the database.
  6. Give proper roles and privileges to the stored procedure being used in the applications.

This posting is provided “AS IS” with no warranties, and confers no rights. 

Composite Web Clients

Today I read about Web Client Software Factory (WCSF) which talks about the challenges faced in the web application development and how to follow proven patterns and practices to overcome these in order to produce reusable loosely coupled code, which can be unit tested. In the series of few posts I will like to add some key points which I have picked about WCSF.  First lets talk about composite web clients. Because the whole WCSF is based to promote composite web clients, lets talk about it a bit more.

A composite Web client application is a Web application that is composed of a number of discrete and independent pieces. These pieces are integrated together within a Web server environment; they are presented to the user in a Web browser as a fully coherent Web client solution. The Composite pattern is a popular and recurring theme because it provides a flexible and scalable architecture that provides several key benefits, including the following:

  1. It allows a higher degree of separation between application infrastructure and business logic.
  2. It allows more independent development of the individual business logic components themselves.
  3. It provides solution agility because business logic components can be flexibly combined to quickly yield a specific solution.
  4. It promotes code re-use because it allows business logic components and the application infrastructure to be re-used across multiple solutions.
  5. It provides an excellent architecture for the front-end integration of line-of-business systems or service-oriented systems into a task-oriented user experience.

ASP.Net 2.0 and composite web clients:- A Web client using the Composite pattern generally involves a shell, which provides the overall user interface structure. For a Web client, the shell is a master page. You can use ASP.NET master pages to create a consistent layout for the pages in your application. A single master page defines the look and feel and standard behavior that you want for all the pages (or a group of pages) in your application. You can then create individual content pages that contain the content you want to display. When users request the content pages, they merge with the master page to produce output that combines the layout of the master page with the content from the content page. Modules contain functionally discrete pieces, but they integrate with the user interface, communicate with the shell, and communicate with each other. The shell provides access to services required by modules throughout the application. This means that the modules can leverage these capabilities instead of having to implement them themselves. This allows a solution to be developed much more quickly because the Web client infrastructure is already in place—the modules can focus on the business logic and their piece of the overall solution instead of focusing on the basic foundation that is required to provide the necessary Web client capabilities.

refer CodePlex for more.

This posting is provided “AS IS” with no warranties, and confers no rights.

Securing Cookies in Web Application

It is important to secure the cookies that are used by the web application. While it is a bad idea to save sensitive information in a cookie anyway, sometimes it becomes almost essential to use cookies. There are three properties that can be set on HttpCookie objects which will make the cookie secured.  We will discuss them: 

  1. fooCookie.HttpOnly = true; - Specifies whether a cookie is accessible by client-side script. By marking the Cookies with HttpOnly clientside scripts are unable to access them.
  2. fooCookie.Secure = true; – Specifies whether to transmit the cookie using Secure Sockets Layer (SSL)–that is, over HTTPS only. Any area of a website or web application that contains sensitive information or access to privileged functionality requires that
    all cookies are sent via SSL during a SSL session. If a cookie is marked secure, it will only be transmitted if the communications channel with the host is a secure one. This means that secure cookies will only be sent to HTTPS (HTTP over SSL) servers. If secure is not specified, a cookie may be captured by an attacker carrying out a man-in-the-middle attack, allowing session
    hijacking to occur.
  3. fooCookie.Path = Context.Request.ApplicationPath; – Sets the virtual path to transmit with the current cookie. It is a good practice to set the cookies path to application root.

This posting is provided “AS IS” with no warranties, and confers no rights.

Posted in .net, asp .net, web. Tags: . 1 Comment »

Edit project files from VS

Here is a cool trick I learnt recently. Most of the time if I need to edit the project files (csproj or vbproj)  manually I open them in notepad or any other text editor.

But what if one needs to edit a project file, while it is loaded in visual studio.

For standard .csproj and .vbproj files do the following:

  • Open the project in Visual Studio 2005
  • Right-click on the project in Solution Explorer and select Unload Project
  • Right-click on the project in Solution Explorer and select Edit <project file>
  • Once you are done editing Save and close the project file
  • Right-click on the project in Solution Explorer and select Reload Project

The benefit of this way is that you don’t need to close the solution and exit visual studio. As well since you are editing it from Visual Studio you get the syntax highlighting and nicely aligned xml file.

AssemblyVersion & AssemblyFileVersion

While both AssemblyVersion and AssemblyFileVersion attributes are used to version the assemblies, but you can use them to differentiate between the assembly version deployed on Live environment as against on your local development machines.

Both are present in the AssemblyInfo.cs (or .vb) class

[assembly: AssemblyVersion("1.0.0.0")][assembly: AssemblyFileVersion("1.0.0.0")]The AssemblyVersion is what other assemblies that reference your namespace will look at. If that number changes, then the referencing assembly will throw an exception. By default is AssemblyFileVersion is not set then it will be same as the AssemblyVersion. Increment it every time a new version of the assembly is deployed.

It is important to note that AssemblyVersion can be set to autoincrement by using *. example:

[assembly: AssemblyVersion("1.0.0.*")] will increment the revision number each time the assembly is built.

I am still not convinced by myself if one will ever need to use two of these seperately. If someone can help me, that will be great.