<2005 July>
SunMonTueWedThuFriSat
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

On this page...

Search

Links

Member of...


ASP Insiders

MVP Visual Developer ASP/ASP.NET

Enter CodeZone

Blog Categories

Microsoft

Blogroll

Deutsche Resourcen

Management

Sign In
 

#  Tuesday, 26 July 2005
The registration for this year's .NET Community Conference in Austria went live today (register here, it's free). The thread of this years rendition is security: threat modeling, .NET 2.0 security features, SQL Server 2005 security and more. Definitely worth your time, if you have time to spare, join us on 12th of August in Vienna!
Tuesday, 26 July 2005 15:37:13 (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]

 

Script Callbacks were also part of my "Advanced ASP.NET 2.0" day at the Community Bootcamp 2005 in Bad Ischl. Aside from showing the usual callback sample, I decided that something more useful was in order. That is why I went a tad further by showing off the controls introduced in the RefreshPanel GotDotNet workspace. I came across those a while back when reading articles on Bertrand Le Roy's blog:

Of course we did labs on CallbackProxy and RefreshPanel, the latter one is described in this blog entry (again, a streamlined version of the lab done by Alexander Schoeppl).

Let's start with the result we wanted to achieve:

The render date only acts as a "proof" that no Postback happened, the dropdown control lists all customers in Northwind and is also populated up front. The GridView control, however, is filled using out of band calls. Instead of hacking your own ugly JavaScript, we did that using the RefreshPanel control.

Step 1: Copy RefreshPanel.dll

First, copy RefreshPanel.dll to the \bin directory of your site. You can get it here.

Step 2: Set up a connection string in web.config

We will use that later both in markup and code beside file:

<connectionStrings>
 <add name="NorthwindConnectionString"
connectionString="Data Source=cbc05vpc\cbc05;Initial Catalog=Northwind;User=sa;Password=P@ssw0rd"/>
</connectionStrings>

Step 3: ShowCustomerOrders.aspx

Basically, "organized" in three sections (separated by a blank line):

<%@ Page Language="C#" AutoEventWireup="true" 
CodeFile="ShowCustomerOrders.aspx.cs" Inherits="Show_Customer_Orders"
Title="Callback Demo" %>
<%@ Register TagPrefix="rp" Namespace="MyControls.RefreshPanel"
Assembly="RefreshPanel" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        Render Date: <asp:Literal ID="Literal1" runat="server"></asp:Literal>
        <br />
       
        <asp:DropDownList ID="DropDownList1" runat="server"
DataSourceID="SqlDataSource1" DataTextField="CustomerID"
DataValueField="CustomerID">
        </asp:DropDownList>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
            SelectCommand="SELECT [CustomerID] FROM [Customers]">
</asp:SqlDataSource>
        <rp:RefreshButton ID="MyButton" RefreshPanelID="RFPanel1"
            runat="server"
            ClientRefreshArgument="this.form.DropDownList1.options[this.form.DropDownList1.selectedIndex].value"
            Text="Show Orders"/>
        <br />
       
        <rp:RefreshPanel runat="server" ID="RFPanel1" OnRefreshing="FillData">
            <asp:GridView ID="GridView1" runat="server">
            </asp:GridView>
        </rp:RefreshPanel>
    </div>
    </form>
</body>
</html>

Register imports the RefreshPanel control suite for us, the Label and DropDown are also very straightforward. The RefreshPanel control itself contains a single GridView control, and it is linked to the server-side method FillData which we will examine in the next step. The RefreshButton is responsible for activating the out of band call back to the server - that's also where we get the value from the dropdown control, and pass it as an event argument to FillData.

Note that the control names are hardcoded, in the real world we'd build that string dynamically, because otherwise we'd get into trouble, eg with master pages.

Step 4: ShowCustomerOrders.aspx.cs

Page_Load is trivial, we are only interested in FillData:

public void FillData(object sender, RefreshingEventArgs e)
{
string connectionString = ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ToString();

string sqlCmd = "Select * from Orders where customerID = @CustomerID";

SqlConnection conn = new SqlConnection(connectionString);

SqlCommand cmd = new SqlCommand(sqlCmd, conn);
cmd.Parameters.AddWithValue("@CustomerID", (string)e.EventArgument);

conn.Open();
SqlDataReader reader = cmd.ExecuteReader();

GridView1.DataSource = reader;
GridView1.DataBind();
reader.Close();
conn.Close();
}

No magic in our code, but: RefreshPanel takes care of giving us a GridView control to work with, and shipping the resulting HTML to the client - and inserting it into the page. Very, very neat indeed.

CallbackDemo.zip (43.51 KB)

Categories: 2 Ohhhh | ASP.NET | this | Training and Conferences
Tuesday, 26 July 2005 15:24:14 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]

 

Via Virtual PC Guy's WebLog: New WinImage Beta with support for editing VHD's. Now that is not only way cool but actually extremely useful if you need that one important file from a virtual machine - now, and not wanting to wait for the vm to start up and then do the copy operation.
Categories: Administration | this | Virtual PC
Tuesday, 26 July 2005 08:20:57 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]

 



#  Monday, 25 July 2005

On Friday, it was my turn as speaker at the Community Bootcamp 2005 aka CBC05. One of the topics at hand was "The Provider Model", with a focus on Membership providers. Those are the ones most likely being extended / written from scratch, and we did an exercise in that very area: Extend the SqlMembershipProvider to audit successful and failed logins similar to *nix. The solution I present today is a streamlined solution programmed by Alexander Schoeppl, one of the attendees.

Step 1: Create the table

CREATE TABLE [dbo].[myLoginAuditing](
 [username] [varchar](255) NOT NULL,
 [numberofSuccessfulLogins] [int] NOT NULL,
 [numberofFailedLogins] [int] NOT NULL,
 [lastFailedLogin] [datetime] NOT NULL,
 [lastFailedLoginIP] [varchar](15) NOT NULL)

Step 2: Create the stored procedure

create procedure myLogUserVisit(
  @username as Varchar(255),
  @success as int,
  @lastfailedLoginIP as varchar(15))
as
   IF ( EXISTS ( SELECT username
                  FROM   dbo.myLoginAuditing
                  WHERE  username = @username ) )
    BEGIN
    if (@success = 1)
    Begin
      update myLoginAuditing set
numberofSuccessfulLogins = numberofSuccessfulLogins + 1
        where username = @username
    End
    else
    begin
      update myLoginAuditing set
numberofFailedLogins = numberofFailedLogins + 1,
                    lastFailedLogin = GetDate(),
                    lastfailedLoginIP = @lastFailedLoginIP
        where username = @username
    end
  END
  ELSE
  BEGIN
    if (@success = 1)
    Begin
      insert into myLoginAuditing (username, numberofSuccessfulLogins,
numberoffailedlogins, lastfailedlogin, lastfailedloginip)
values (@username, 1, 0, '01.01.1900', '')
    End
    else
    begin
      insert into myLoginAuditing (username, numberofSuccessfulLogins,
numberoffailedlogins, lastfailedlogin, lastfailedloginip)
values (@username, 0, 1, GetDate(), @lastfailedLoginIP)
    end   
  END

Alexander did a smart thing - he looked at the various aspnet* sp's.

Step 3: Write the Membership provider

The class skeleton looks like this:

public class MyMembershipProvider : SqlMembershipProvider
{
public override bool ValidateUser(string username, string password)
{
}

public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
}

public override MembershipUser GetUser(string username, bool userIsOnline)
{
}
}

Initialize is the easy but essential part - we need the connection string name for later:

private string connectionStringName;

public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
connectionStringName = config["connectionStringName"];
base.Initialize(name, config);
}

Now we can validate the user - well, the base class does that. We only do the auditing part:

public override bool ValidateUser(string username, string password)
{
HttpContext.Current.Trace.Write("ValidateUser:entry");

bool bSuccess = base.ValidateUser(username, password);

string connectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;

SqlConnection conn = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand("exec myLogUserVisit @username, @success, @IP", conn);

cmd.Parameters.AddWithValue("@username", username);
if (bSuccess)
  cmd.Parameters.AddWithValue("@success", 1);
else
  cmd.Parameters.AddWithValue("@success", 0);

cmd.Parameters.AddWithValue("@IP", HttpContext.Current.Request.UserHostAddress);

conn.Open();
cmd.ExecuteNonQuery();
conn.Close();

HttpContext.Current.Trace.Write("ValidateUser:exit");

return bSuccess;
}

Step 4: Set it up - web.config

  <appSettings/>
  <connectionStrings>
    <add name="MyNWind" connectionString="Data Source=cbc05vpc\cbc05;Initial Catalog=Northwind;User=sa;Password=P@ssw0rd"/>
  </connectionStrings>
 
  <system.web>
    <membership defaultProvider="SuperDuperMSProv">
      <providers>
        <clear/>
        <add name="SuperDuperMSProv" connectionStringName="MyNWind" type="MyMembershipProvider"/>
      </providers>
    </membership>

Step 5: View the auditing information - default.aspx.cs

The final "UI" looks like this:

The source code is rather simple:

protected void Page_Load(object sender, EventArgs e)
{
MyMembershipUser currentUser = (MyMembershipUser)Membership.GetUser();

Label1.Text = currentUser.FullName;
string lcConnection = ConfigurationManager.ConnectionStrings["MyNWind"].ConnectionString;

SqlConnection conn = new SqlConnection(lcConnection);

SqlCommand cmd = new SqlCommand("select * from myLoginAuditing where username=@username", conn);
cmd.Parameters.AddWithValue("@Username", currentUser.UserName);

conn.Open();

SqlDataReader reader = cmd.ExecuteReader();

GridView1.DataSource = reader;
GridView1.DataBind();

reader.Close();
conn.Close();
}

Done. By the way, did you notice something? Right! Alexander never fell into the trap of SQL Injection.

ExtendingMembershipProviderDemo.zip (5.64 KB)

Categories: 2 Ohhhh | ASP.NET | Community | Security
Monday, 25 July 2005 19:46:16 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]

 



#  Wednesday, 13 July 2005
Yet another security book is coming: The 19 Deadly Sins of Software Security. You can read about its contents on Michael Howard's blog here. I am not yet done with Protect Your Windows Network : From Perimeter to Data by Jesper Johansson and Steve Riley (great site, btw). I definitely do recommend this book to everyone interested in security!
Categories: Books | Security
Wednesday, 13 July 2005 08:16:30 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]

 



#  Tuesday, 12 July 2005
Order a couple of their security posters and place them at strategical locations in your company. Maybe someone should buy this poster for the UK MOD - they keep having their notebooks stolen.
Categories: Security
Tuesday, 12 July 2005 22:05:59 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]

 

Check out the article 10 Immutable Laws of Security on TechNet. A couple of those should get you thinking - I especially like #6.
Categories: Administration | Security
Tuesday, 12 July 2005 21:59:45 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]

 



#  Monday, 11 July 2005

Process Explorer is a really nifty tool, that comes in very handy when you want to take a deep dive into what's running on your machine, and what might be happening behind the scenes:

When you double-click on a .NET application, you get a tab dedicated to AppDomain and performance counter information:

Nice for a quick look around to see what that application is doing.

Categories: .NET | Cool Download
Monday, 11 July 2005 15:50:36 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]

 

Mark Russinovich (his blog is highly recommended) commented on that book during one of his TechEd Europe talks. The book is written (including) by the guy running rootkit.com, famous for the Hacker Defender rootkit for Windows. Looks like there's yet another book to be added to my backlog for reading this summer <g />.
Categories: Books | Security | this
Monday, 11 July 2005 15:01:12 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]

 

And it works just fine (here you can get one for yourself):

Categories: Smartphone and PocketPC | this
Monday, 11 July 2005 09:51:43 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]

 



© Copyright 2017 Christoph Wille

newtelligence dasBlog 2.3.9074.18820
Subscribe to this weblog's RSS feed with SharpReader, Radio Userland, NewsGator or any other aggregator listening on port 5335 by clicking this button.   RSS 2.0|Atom 1.0  Send mail to the author(s)

 
Don't contact us via this (fleischfalle@alphasierrapapa.com) email address.