The Problem Solver

Tell me and I will forget
Show me and I will remember
Involve me and I will understand
- Confucius -

Using the ASP.Net membership provider in a Windows forms application part 4.

In my last three blog entries I showed how to use the ASP.Net membership provider in a Windows application. I finished with the problem of storing the current user name and the fact that there is a second overload to the IsUserInRole() function that only takes a role name. Well it turns out that this function checks for the current user and uses either the HttpContext.Current.User or the Threading.Thread.CurrentPrincipal depending on the fact if the application is hosted. As the Threading.Thread.CurrentPrincipal is the normal way access is provided to the current user and role information in a windows application this seems like the natural thing to do.

 

The System.Web.Security.RolePrincipal class implements the required IPrincipal interface so this is the class we need to use. To create the required object we need an IIDentity object to provide the user identity information. This can be provided using the System.Security.Principal.GenericIdentity class that implements the IIdentity interface.

 

Add the following code to the top of the Module1.vb:

Imports System.Security.Principal

 

Now we can set the principal and check for specific roles using the following code:

        Dim user As MembershipUser = Membership.GetUser("Maurice")
        Dim identity As New GenericIdentity(user.UserName)
        Dim principal As New RolePrincipal(identity)
        Threading.Thread.CurrentPrincipal = principal

        If Roles.IsUserInRole("Developer") Then
            Console.WriteLine("Is a developer.")
        Else
            Console.WriteLine("Doesn't write code.")
        End If

 

An alternative way of checking the user and role is:

        Console.Write(Threading.Thread.CurrentPrincipal.Identity.Name)
        If Threading.Thread.CurrentPrincipal.IsInRole("Developer") Then
            Console.WriteLine(" is a developer.")
        Else
            Console.WriteLine(" doesn't write code.")
        End If

 

So the complete console application now looks like:

Imports System.Security.Principal
Imports
System.Web.Security

Module Module1
    Sub Main()
        ' Creating a new user
        Dim status As MembershipCreateStatus
        Membership.CreateUser( _
            "Maurice", _
            "Password_1", _
            "maurice@TheProblemSolver.nl", _
            "Password question", _
            "Password answer", _
            True, _
            status)
        ' Check the status for errors
        Console.WriteLine(status.ToString())

        ' Validate a username/password
        If Membership.ValidateUser("Maurice", "Password_1") Then
            Console.WriteLine("User validated.")
        Else
            Console.WriteLine("User invalid!")
        End If
 

        ' Create a new Developer role.
        ' Add the <roleManager enabled="true" /> to the app.config for this to work
        If Not Roles.RoleExists("Developer") Then
            Roles.CreateRole("Developer")
        End If

        ' Add a new role to a known user.
        If Not Roles.IsUserInRole("Maurice", "Developer") Then
            Roles.AddUserToRole("Maurice", "Developer")
        End If

        ' Create a second user with only username/password
        ' Add the <membership><providers> element to the app.config first
        Dim user As MembershipUser
        user = Membership.GetUser("User2")
        If user Is Nothing Then
            user = Membership.CreateUser("User2", "p")
            Console.WriteLine(user.UserName)
        End If


        ' Check is a specified user is in a specific role
        If Roles.IsUserInRole("Maurice", "Developer") Then
            Console.WriteLine("Is a developer.")
        Else
            Console.WriteLine("Doesn't write code.")
        End If 

        ' Set the current application principal information to a known user
        Dim identity As GenericIdentity
        Dim principal As RolePrincipal
        user = Membership.GetUser("Maurice")
        identity = New GenericIdentity(user.UserName)
        principal = New RolePrincipal(identity)
        Threading.Thread.CurrentPrincipal = principal

        ' Check if the current principal is in a specific role
        If Roles.IsUserInRole("Developer") Then
            Console.WriteLine("Is a developer.")
        Else
            Console.WriteLine("Doesn't write code.")
        End If


        ' Set the current application principal information to another known user
        user = Membership.GetUser("User2")
        identity = New GenericIdentity(user.UserName)
        principal = New RolePrincipal(identity)
        Threading.Thread.CurrentPrincipal = principal

        ' Use the principal to check for role information
        Console.Write(Threading.Thread.CurrentPrincipal.Identity.Name)
        If Threading.Thread.CurrentPrincipal.IsInRole("Developer") Then
            Console.WriteLine(" is a developer.")
        Else
            Console.WriteLine(" doesn't write code.")
        End If

        Console.ReadLine()
    End Sub
End
Module

 

 
<?
xml version="1.0" encoding="utf-8" ?>
<
configuration>
  <
system.web>
    <
roleManager enabled="true" />
    <
membership
      <
providers>
        <
remove name="AspNetSqlMembershipProvider"/>
        <
add name="AspNetSqlMembershipProvider"
            
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
            
connectionStringName="LocalSqlServer"
            
enablePasswordRetrieval="false"
            
enablePasswordReset="true"
            
requiresQuestionAndAnswer="false"
            
applicationName="/"
            
requiresUniqueEmail="false"
            
passwordFormat="Hashed"
            
maxInvalidPasswordAttempts="5"
            
minRequiredPasswordLength="1"
            
minRequiredNonalphanumericCharacters="0"
            
passwordAttemptWindow="10"
            
passwordStrengthRegularExpression="" />
      </
providers>
    </
membership>
  </
system.web>
</
configuration>
 

Maurice de Beijer
www.TheProblemSolver.nl

Published Sun, Jan 15 2006 19:43 by Maurice

Comments

# re: Using the ASP.Net membership provider in a Windows forms application part 4.@ Tuesday, April 25, 2006 5:44 PM

Hi, do you know how can i get the value of User.Identity.Name when a assigned the RolePrincipal straighforward in Thread.CurrentPrincipal?

Regards

by Miguel A. Palizada

# re: Using the ASP.Net membership provider in a Windows forms application part 4.@ Monday, May 29, 2006 8:41 AM

Hi Miquel,

Using the following: System.Threading.Thread.CurrentPrincipal.Identity.Name will do the trick.

Maurice

by Maurice

# re: Using the ASP.Net membership provider in a Windows forms application part 4.@ Friday, June 01, 2007 4:13 PM

Hi Maurice. Great article. Congratulations. How can i use my own data base (e.g., MyApp.mdf) instead ASPNETDB.MDF ?

Thanks,

Edison

by Edison Costa

# re: Using the ASP.Net membership provider in a Windows forms application part 4.@ Saturday, June 02, 2007 5:34 AM

Hi Edison,

There are two easy ways of doing this. Either set the LocalSqlServer connection string to point to your own database. The drawback, or advantage depending on your point of view, is that other providers use the same connection string and are. The other solution is to use a different connection string name in the connectionStringName="LocalSqlServer" line in the app.config. This way you can specify a different database for just the membership provider.

by Maurice

# re: Using the ASP.Net membership provider in a Windows forms application part 4.@ Monday, June 18, 2007 12:33 PM

Maurice,

I have a VS.NEt 2002 running on a Windows 2000 server that uses the System.Threading.Thread.CurrentPrincipal.Identity.Name  code to capture the  user ID.  However, it does not work on a Windows 2003 server.  Any ideas?

by Gary Young

# re: Using the ASP.Net membership provider in a Windows forms application part 4.@ Tuesday, June 19, 2007 4:27 AM

Are you running a web app? In that case you need to use the HttpContext.Current.User.Identity.Name.

Otherwise you can try AppDomain.CurrentDomain.SetPrincipalPolicy(System.Security.Principal.PrincipalPolicy.WindowsPrincipal) and see if that makes a difference.

by Maurice

# re: Using the ASP.Net membership provider in a Windows forms application part 4.@ Saturday, August 11, 2007 7:32 PM

Can you give an example of a valid connection string that points to the same database name in a different location?

by Kevin

# re: Using the ASP.Net membership provider in a Windows forms application part 4.@ Saturday, November 03, 2007 7:47 AM

Hi Maurice. I'm currently implementing a custom MembershipProvider and MembershipUser class (inherited).

What's the difference with regards to the App.Config file?

by Raymond

# re: Using the ASP.Net membership provider in a Windows forms application part 4.@ Monday, February 25, 2008 4:20 PM

Hi Maurice,

I can get user list on web form like that;

-----------

ListBox1.DataSource = Membership.GetAllUsers();

ListBox1.DataBind();

-----------

But it does not work on windows form, the Membership.GetAllUsers() returns NULL.

but for one user;

MembershipUser user = Membership.GetUser("username")

works good.

Do u have any idea to get the user list for a Windows form ?

Thanks...

Adam

by Adam Right

# re: Using the ASP.Net membership provider in a Windows forms application part 4.@ Tuesday, February 26, 2008 10:21 AM

Hi Adam,

If I am not mistaken Membership.GetAllUsers() should return an (empty) collection instead of null or Nothing is everything is configured right. Both the Membership.GetAllUsers() and Membership.GetUser("username") use the same mechanisms and connection string behind the scene.

by Maurice

# re: Using the ASP.Net membership provider in a Windows forms application part 4.@ Friday, March 21, 2008 3:33 PM

you need to provide a provider for the roleManager in order to store role information in a database of your choice.

by olli

# re: Using the ASP.Net membership provider in a Windows forms application part 4.@ Friday, May 02, 2008 12:29 PM

Hi,

I try to implement your code in other example:

- 1) Winform that call a webservice

- 2) Webservice with Custom UserNameToken with protected override string AuthenticateToken( UsernameToken token )

- 3)Sql Server version is Standard version on my Server, but this database is configured by aspnet_regsql.exe.

All works correctly to create user(like your example) in the webservice, but when i try to validate the user (Membership.ValidateUser("Maurice", "Password_1"), i have this error:

The indicator opening session of instant user is not supported in this version of SQL Server.

Do you have a idea?

Thanks

# re: Using the ASP.Net membership provider in a Windows forms application part 4.@ Wednesday, June 04, 2008 3:17 AM

thanks for uy code

by venky

# http://ghjejrpyupyuptlhy.com ghjejrpyupyuptlhy,mjkl9qi7wqyq@representative.com,Good site@ Sunday, July 13, 2008 5:06 AM

http://ghjejrpyupyuptlhy.com ghjejrpyupyuptlhy,http://ghjejrpyupyuptlhy.com ghjejrpyupyuptlhy

# re: Using the ASP.Net membership provider in a Windows forms application part 4.@ Wednesday, March 25, 2009 8:58 AM

Thanks, Nice code.

by Sujan

# thanks @ Friday, May 29, 2009 7:41 AM

everything is working fine like im in asp.net

thanks for your effort

by nerio