How to develop and deploy DNN Schedule Task

by Naveen 19. September 2011 15:15

Every now and then we all run into development of functionality in ASP.Net that requires do some scheduled tasks that need to be done at some pre-defined time and frequency. Same is true for development in DNN. Fortunately DNN framework provides a built in framework that allows you to develop custom scheduled tasks and then deploy them into the portal. The process is very straight farward. There are some caveats that you need to be aware of when developing schedules tasks in DNN. I will focus on those caveats in this post exclusively.

DNN Schedule Task Development

To get started you will need a .Net assembly developed that has a class that derives from ScheduleClient class. If your schedule task is part of an existing module then you can add a new class to the same module project. Otherwise you will need to create a new library project. Here is how new class definition may look like.

using DotNetNuke.Services.Scheduling;
public class ReminderScheduler : SchedulerClient
{
  public ReminderScheduler()
  { }

  public ReminderScheduler(ScheduleHistoryItem historyItem)
            : base()
  {
            this.ScheduleHistoryItem = historyItem;
  }
  public override void DoWork()
  {
  	this.Progressing();
    //   ... Add schedular implementation here ...
    this.ScheduleHistoryItem.Succeeded = true;
    this.Completed();
  }
}

As you can see that I have included Scheduling namespace in this class. You will need it for SchedulerClient definition. DNN uses reflection to create object of scheduler's class and passes ScheduleHistoryItem as constructor argument. It is important that implement the parameterized constructor for your class so can set the instance of this ScheduleHistoryItem object in your implementation. You will need this ScheduleHistoryItem object for lot of things during the implementation. For example to record log messages for your task you can use this object to record messages. DoWork is the method that gets executed when scheduler needs to run. You put all the implementation related to your scheduled task in this method.

You indicate progress of your task by calling Progressing method and then indicate finish by calling Completed method. It is best practice to call this method to inidcate start and finish to let DNN framework do its book keeping and clean up. You will set property Succeeded on ScheduleHistoryItem object. Now you can see why it is important to have parameterized constructor implemented. If you do not do so then any attempt to use ScheduleHistoryItem object will end up exception thrown from your scheduled task implementation.

No HttpContext

This is very important part of the implementation that you will have to understand. You may think that since scheduled task is deployed in your DNN portal there will always be web context to work with. That is not the case. These scheduled tasks are dispatched on separate threads. The context of these threads is not your web application. So if you try to use objects like HttpContext.Current you will end up with exception. Therefore it is very important that whatever implementation you put in place for your task, you do not rely on web context.

Deploying Schedule Task In DNN

You will have to log in with host account to access the menu item used to deploy schedule task(s). Click on Schedule option and then on that page click on Add Item to Schedule. You will be presented with UI that looks as below (as of version 5.6.2).

dnn schedule task

Fill the information as asked in that interface. It is very important that you provide fully qualified name of the class for your schedule task. Rest of the imformation is very self explanatory. Once your tasks is deployed it will run as per the schedule you specified.

 

Views: 1016

Tags:

ASP.Net | DotNetNuke

DNN - Create Custom Event Log Type Entries

by Naveen 23. June 2011 19:50

Logging of events, success or failures, during life of an application is very integral part of diagnostics. When something goes wrong happens first place I would like to go is to some log table (database, file etc.) to find out what went wrong. I am not going to discuss what it is important to implement logging mechanism in your application. There are plenty of books, article and posts that provide some good discussion on this design decision. In this post I am going to focus on how do you use logging and provide custom events. DotnetNuke provides built in mechanism for logging of all the events. You can look at these events under Admin > Event Viewer menu when you log in with admin or host account.

When you look at the event viewer page you will find lot of entries. Some of those entries are informative and some would be related to exceptions and errors that occur during life of application. Let me first show how these entries make it to the tables in the database or any logging mechanism in DNN. Following code snippet shows the simplest implementation that you can put in your DNN module to log some entries.

var logController = new EventLogController();
var logInfo = new LogInfo();
logInfo.LogPortalID = portalSettings.PortalId;
logInfo.BypassBuffering = true;
logInfo.LogTypeKey = logType;
logInfo.AddProperty("Message", message);
logController.AddLog(logInfo);

I will describe this code in details as I discuss the logging mechanism during the course of this post. You can see how easy it is to add entries in the event log of DNN portal. The key to this code snippet and logging of event is LogTypeKey property of LogInfo object. When you look at event log, there is a column named Log Type in the grid as you can see from the image below.

DNN Event Log Viewer

You will notice that above the log grid, there is Type dropdown list. If you look at all entries in this list, you will find that the names in this list match some of the entries in the event log. Yes, each entry in the event log is associated with these types. This means that you just can not have som arbitrary name specified for log type entry. Each of these entries have a unique name associated with it which acts as LogTypeKey. Look at the tables for your DNN installation and you will find two tables dnn_EventLogTypes and dnn_EventLogConfig that control the logging mechanism. If you look at the entries in dnn_EventLogTypes, you will find all the names in Types dropdown list in LogTypeFriendlyName field. And there is a field named LogTypeKey that stores unique names for each of the log type. And for each of these LogTypeKey values there are entries in dnn_EventLogConfig table that define attributes for each of these log types. Most importnat of the fields in that table is LoggingIsActive. This is the field that control if entry for that type of log will be entered in the database or not.

DNN Event Log Types

If you specify value of LogTypeKey that does not exist in dnn_EventLogTypes table, the call for AddLog method on EventLogController simply returns without adding any entry in the database for the message that you are trying to add. If you want to use the built in event types, then you can use simply use of the values from DotNetNuke.Services.Log.EventLog.EventLogType enum.

Color Coding Of Entries In Event Log

When you look at entries in event viewer grid, you will notice that different event types are represented with different color or styles. These colors or styles come from LogTypeCSSClass field in dnn_EventLogTypes tables. You will notice heading Color Coding Legend above the event log grid. If you click on + icon on left, it will expand to a section showing colors for different log type entries as show in image below.

DNN Event Log Type Color Styles

Custom Event Log Type In DotnetNuke

When you are doing custom module development for DotnetNuke, then you want to have entries in the log that are specific to your module only. By doing this, it makes it very easy for you to filter the view to see what all errors or activities are present in the event log for your module. To add custom entries in event log, you have to perform following two steps before you could use AddLog method to add log entries.

Add New Log Type Key

Pick a unique name that will be used as key for your custom log entry type. And then decide on a friendly name that will be displayed in the event log view for custom event. Then you can use following code to add your log type.

var logController = new LogController();
var logTypeInfo = new LogTypeInfo();
logTypeInfo.LogTypeCSSClass = "MyEventCssClass";
logTypeInfo.LogTypeDescription = description;
logTypeInfo.LogTypeFriendlyName = "My friendly name for event";
logTypeInfo.LogTypeOwner = "DotNetNuke.Logging.EventLogType";
logTypeInfo.LogTypeKey = "My Module Event Key"; // Pick unique key name
logController.AddLogType(logTypeInfo);

In the code above replace the values for LogTypeCSSClass, LogTypeKey, LogTypeFriendlyName and LogTypeDescription properties with the ones that you want to use for your custom event. You can not add the same key twice. If you call AddLogType with same LogTypeKey again, you will end up with following error.

Violation of PRIMARY KEY constraint 'PK_dnn_EventLogTypes'. Cannot insert duplicate key in object 'dbo.dnn_EventLogTypes'.

Activate Custom Event Type

After you have added your custom log type, you will need to set its attribute to make it active for logging. This is done by using AddLogTypeConfigInfo method on LogController. Following code snippet shows some code from my module.

var logTypeConfigInfo = new LogTypeConfigInfo();
logTypeConfigInfo.LogTypeKey = logTypeKey;
logTypeConfigInfo.LoggingIsActive = true;
logTypeConfigInfo.MailFromAddress = mailserver;
logTypeConfigInfo.MailToAddress = mailTo;
logTypeConfigInfo.EmailNotificationIsActive = false;
logController.AddLogTypeConfigInfo(logTypeConfigInfo);

The most important property of LogTypeConfigInfo object is LoggingIsActive. If you do not set this property, your custom log type will stay inactive and any AddLog method call will be ignored. You can call AddLogTypeConfigInfo multiple types. The underlying stored procedure checks for existing settings. If there is already one for that log type, it simply updates the vlaues in the table.

Custom Event Log Type Ready!

One you have performed above two steps, you are all set to use your custom event log type in DNN module. Since you can add entries in dnn_EventLogTypes only one time, you will have to make sure that you do not attempt to add more than one time. Check if certain log type already exists before adding. Following code snippet from my custom module shows how it can be done.

public static bool LogTypeKeyInstalled(string logTypeKey)
{
   var eventLogController = new EventLogController();
   var logTypes = new List<LogTypeInfo>
      (eventLogController.GetLogTypeInfo().Cast<LogTypeInfo>());
   return logTypes.Any(lt => lt.LogTypeKey == logTypeKey);
}

if (!LogTypeKeyInstalled("LOAD_FAIL"))
{
 // Perform add operation for custom log type
}

Now we are all set with custom log type!

 

Views: 1809

Tags:

DotNetNuke

The value for the 'compilerVersion' attribute in the provider options must be 'v4.0' or later

by Naveen 25. May 2011 15:25

While moving my ASP.Net application from Windows 2003 server to Windows 2008 R2 server I ran into following exception when I tried to access the application.

The value for the 'compilerVersion' attribute in the provider options must be 'v4.0' or later if you are compiling for version 4.0 or later of the .NET Framework. To compile this Web application for version 3.5 or earlier of the .NET Framework, remove the 'targetFramework' attribute from the element of the Web.config file.

Well this took me by surprise a little because this application has been working for over a year on Windows 2003 server. I remembered that since this was child application under parent DNN portal, I had to add following entry in web.config. From being a child application means that my application was configured as another web application under DNN web application.

<location path="" inheritInChildApplications="false" >

So my first thought based on the exception details was that probably by mistake somebody removed that entry. Well that was not the case. Then I checked the application pool for parent as well as child application. They both were configured to use application pool that was using .Net 4.0 with classic pipe line. Then I looked at compiler options in my child application. It was set as follows and nothing seemed to be wrong here as well.

<compilation debug="true" targetFramework="4.0" />

Only place left was to check in parent application. After digging through million entries in DNN web.config file, I found the following that had compiler option set to V3.5.

<compiler language="vb;vbs;visualbasic;vbscript" 
type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, 
Culture=neutral, PublicKeyToken=b77a5c561934e089" extension=".vb" warningLevel="4">
   <providerOption name="CompilerVersion" value="v3.5" />
   <providerOption name="OptionInfer" value="true" />
   <providerOption name="WarnAsError" value="false" />
</compiler>
<compiler language="c#;cs;csharp" 
extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider,System, 
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" warningLevel="4">
   <providerOption name="CompilerVersion" value="v3.5" />
   <providerOption name="WarnAsError" value="false" />
</compiler>

After I changed the compiler version to V4.0, my application was happy as a pie! Here is link to Microsoft document on breaking changes that describes this issue in more detail.

ASP.NET 4 Child Applications Fail to Start When Under ASP.NET 2.0 or ASP.NET 3.5 Applications
 

Views: 2129

Tags: ,

ASP.Net | DotNetNuke | IIS

DNN Performance Optimization - How DNN Caching Works

by Naveen 11. May 2011 06:56

Caching of data and content plays a big part in performance optimization of any application. This statement is not limited to a web application. It is pretty much true for any kind of application. In this post I will not be discussing what is caching and why do it. You will find lot of good resouces about this on internet.

DNN is no different in this regard that caching can affect performance and some time operations of your web portal. Recently I spent some time researching how caching works in DNN. And I found some very interesting and useful information that answered a lot of questions that lot of DNN users have asked me in the past and I did not have definite answers. In this post I am going to discuss some DNN implementation details that will help you understand caching in DNN little better.

Cache Time Settings

Lets first look at all the places from where you can control caching in DNN.

Host Settings > Performance Settings

As header suggests and you can see from screenshot below, first place to control caching is in Host Settings. I will explain little later what the settings under Cache Setting mean and how they affect caching on your portal.

dnn host settings

Module > Settings

Next comes the entry in module's settings. As you can see from screenshot below, you will find this is under Page Settings section of a module settings.

Caching Provider

Now that you have see how to set cache time, next you will need to know the caching method used by DNN. Out of the box you have two options, File based and Memory. As the name suggests, Memory based caching is your standard ASP.Net inproc cache object. File based caching stores cached content on the disk itself.

FileCacheProvider

DNN stores cached content in a folder under each portal in Portals\0\Cache\Pages folder. There you will find files containing cached content. You will notice that there are two types of files in that folder. For example following are two entries from my machine.

44_ACABA51644A302FBB325E30E7931BAF8.attrib.resources
44_ACABA51644A302FBB325E30E7931BAF8.data.resources

First part of the file name is unique cache key that identifies the resource. Second part of file name is either data or attrib. The file with name attrib stores time when the cache item is suppose to expire. The file with name data stores actual content of the cached item. So if you delete any one of these two files, you will end up trashing the cached content for that item.

Now you are wondering how does cached entries get cleaed up or refresh. DNN launches a thread when application starts. This thread runs on one minute interval. Every minuts it goes through this folder and reads attrib files to decide what content files need to be deleted. This thread performs its action asynchronously so there is minimal performance impact of this thread.

So if you ever feel the need to manually clear cache of your portal, go to the folder and delete all the files and you will be good. Only caveat is that if your site is live, there is a good chance that cache file may be in use and locked if some user is accessing the site. You can retry deleting the file.

How does DNN caching works?

Host Settings

In DNN caching works at different levels. First lets see what Cache Setting values in Host setting mean. There are four posisble values that you can set. These four values are actually multipliers used with cache time value. Following are values for these multipliers.

  • None - 0
  • Light - 1
  • Moderate - 3
  • Heavy - 6

DNN uses these value with caching of module settings. Yes, it is not for caching of module content. It is actually module settings. You do not want DNN to make a call into database to get settings for the module for every single user and every single tab. It will put a lot of load on your database and site will be slow. DNN uses 20 minute cache time for module settings. You can affect this time by changing value of Cache Setting. For example if you have set this value to moderate, it would mean that module settings are going to be caches for 20 * 3 = 60 minutes.

Well, this module cache time out setting is well and good when you are using DNN UI to make modifications to modules. But if you directly want to change your module's settings in database, then you are at a loss because portal has those settings cached. This would mean that you will have to some how trigger cache refresh on your module.

Module Settings

Caching of module's content is controlled by time you set in module's settings. This time value is not affected by Cache Setting value in host setting. If you do not want DNN to cache content of your module, then set this value to 0. When you hit Update in module settings, DNN clears the cache for the module as well as that tab. And your users will see fresh content. If you will change cahe time for module directly in database, it is not going to take into affect till cache time has expired for the module. That means you will have to goto DNN UI to hit update or clear the cache for the module by hitting Update link.

File Based Cache and Application Restart

As I described earlier how file based caching works. Here is little caveat that may affect you. When you restart IIS or web server, you probably are expecting all cached items to be cleaned up. This is the behavior you are used to when using InProc or OutofProc caching in ASP.Net. In DNN when you use File based caching, the items are not cleared from cache folder untill the time that is set in attrib file for that item. So if you restart IIS or your server, when DNN application comes back up, it will pick up the cached content if not expired so far. This can be good or bad depending on your situation. If you restarted IIS or Web server to refresh content of portal after some major changes, then you are at loss because DNN will read the content from old cache files. But if restart was for some maintence on server then you are good because your application is already primed with cached content.

This is where Clear Cache and Restart Application links in Module Settings and Host Settings will help you. If you need to dump the cache in your portal, use these links.

This is how DNN caching works under the cover for you. This information is based on DNN 5.6.2 community version. The implementation may have changed since I reviewed the implementation or it may be different from Professional version.

 

Views: 2318

Tags:

ASP.Net | DotNetNuke

Debugging Why DNN Installation Wizard Is Launched

by Naveen 9. May 2011 04:56

When you are upgrading a DNN portal or moving the portal from one server to another or attaching to some existing or different database, you may end up with a situation where Installation Wizard screen comes up for you. Every time InstallaWizard.aspx page comes up in your DNN portal, it means that DNN framework thinks that it is a new install of the portal. This could be very embarassing situation in a live portal. Imagine, you make some changes on server and your user is presented with installation wizard.

It is important that we all understand what are the factors involved that can cause this installation wizard to appear. When your DNN portal starts it goes through a series to checks to decide if it needs to prompt the user to perform a new install or upgrade of the portal.

Is Database provider installed?

First test is performs is a check on Providers/Data Providers folder under your web application. If this test passes, then it tries to get DNN dataabase version. This test is performed by calling dnn_GetDatabaseVersion stored procedure. If you have a good installtion of DNN, you will find this sproc in your DNN database. .Net will throw SqlException if you do not have a database installed or for some reason it is corrupted. DNN looks for SQL Error Code: 2812 with Severity Level: 16. This error code translates to Could not find stored procedure. If there is any other error, DNN tags the error message with suffix ERROR: and then subsequent code goes to next test. If DNN does not find this sproc in your database, then no further tests are performed and status of your execution is set to Install and you are presented with InstallWizard screen.

Four Factors To Check

If database check ends up with a status message starting with ERROR:, DNN performs further tests to determine status. It checks for following things:

  • Do you have a InstallationDate entry in web.config file? This test add a score of 1.
  • Do you have HTML module installed under DesktopModules folder? This test adds a score of 2.
  • Do you have Portals directory in your web application folder? This test adds a score of 2.
  • Do you have *.log.resources files in your Providers folders? This add a score of 3.

If test passes with a score of 4 or higher then your installation is considered good. Otherwise your status is set to Install. This test is not a deterministic test but provides a good indicator of health of your installation.

Troubleshooting

If you are having problem of InstallWizard.aspx coming up in your already installed DNN portal, start with answering questions for above tests and then go from there.

 

Views: 1313

Tags:

DotNetNuke

Import User Accounts into DNN

by Naveen 8. May 2011 20:55

Recently I worked on creating a portal using DNN5.6. This portal was going to replace an existing site that was built with every early version of DNN that used .Net1.1. After completing the site came the time to import all the users from existing site to new site. The latest site used ASP.Net SQL Membership provider. User management tables in old DNN are very different from how DNN uses ASP.Net membership provider in latest version of DNN. To import DNN users from old version, I had to do some research on new database tables involved. In this post I will try to provide some details on all the tables involved in user account managements in DNN that uses SqlMembershipProvider.

MemberShipProvider Table

DNN uses following two tables to store bare minimum login information for a user.

  • aspnet_Users
  • aspnet_Membership

SqlMembership provider stores user's password in aspnet_Membership table where as user ID as primary key is stored in aspnet_Users table. These two tables are used to perform first stage of authentication for a DNN user.

DNN User Tables

DNN maps SqlMembershipProvider user accounts to DNN user accounts in following tables.

  • dnn_Users
  • dnn_UserPortals
  • dnn_UserRoles

Every membership user account has an entry in dnn_Users table. DNN uses a single sign-on for a user for all portals. An entry in dnn_UserPortals determine user's access to individual portals. By default a user is not assigned any roles. If you need to assign certain role(s) to user accounts, then look in dnn_Roles tables and then appropriate entries need to be created in dnn_UserRoles table.

You do not have to manually create any entries in these tables. I would highly recommend using stored procedures created by DNN to take care of all the database tasks involved in creating user account(s). Here is simple procedure to follow.

  • Use Membership object to create user's account in membership provider. This can be accomplsihed by Membership.CreateUser method.
  • Now call dnn_AddUser stored procedure to create DNN user account mapping to membership provider user.
  • If you need to assign role(s) to user account, then call dnn_AddRole stored procedure for each user.

This should get you started with importing user accounts into DNN.

 

Views: 1425

Tags:

DotNetNuke

Decrypt user password in ASP.Net SqlMembershipProvider

by Naveen 3. May 2011 13:45

In this post I will discuss decoding of encrypted passwords in ASP.Net SqlMembershipProvider table. This discussion will help answer to questions as follows:

  • How to decrypt passwords stored database created by SqlMembershipProvider?
  • How to decrypt passwords in DNN (Dotnetnuke)?
  • How to extend a memebership provider object?
  • And more questions related to ASP.Net membership provoider using Sql database...

If you are using Microsoft provider SqlMembershipProvider in DNN or any other ASP.Net application, look in the database and you will find a table aspnet_Membership. This is where passwords are stored. Depending on how you configured your membership provider, these passwords may already be in clear text. This behavior is controlled by an attribute in definition of membership provider in config file of your application.

passwordFormat="Encrypted"

There is PasswordFormat field in the database table as well. That means handling of password values depends very heavily of this value. If your passwords are encrypted, then the value of this field is set to 2.

Algorithm for encrypt and decrypt of password

Next you need to know what algorithm and key is used to encrypt and decrypt the password. Default implementation of Membership provider picks up these values from machineKey settings from your config file. So in your config file under system.web you will notice an entry like:

<machineKey validationKey="AD3642D1C078D34C05741E5A63514C784......." 
decryptionKey="F18D8F1FA9F986B26B9F0C8CB4067CAC45E25F4BD6........" 
decryption="3DES" validation="SHA1" />

This is where your algorithm and keys are defined. And this is what default implementation of SqlMembershipProvider uses.

How to decrypt password?

MembershipProvider class has DecryptPassword and EncryptPassword methods that are used by SqlMembershipProvider. When I started researching this topic, I found suggestions on creating a new class that inherits from MembershipProvider class and then call DecryptPassword method to do the job. Well I did try that approach and it did not work. I always ended up with following exception.

Unable to validate data.

   at System.Web.Configuration.MachineKeySection.EncryptOrDecryptData
   (Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length,
    Boolean useValidationSymAlgo, Boolean useLegacyMode, IVType ivType, Boolean signData)
   at System.Web.Security.MembershipAdapter.EncryptOrDecryptData(Boolean encrypt, 
   Byte[] buffer, Boolean useLegacyMode)
   at System.Web.Security.MembershipProvider.DecryptPassword(Byte[] encodedPassword)
   at MembershipPasswordRecover.NetFourMembershipProvider.GetPassword(String encPwd) in 
   at MembershipPasswordRecover.Program.Main(String[] args) in 

After looking through the code in reflector, I saw that Microsoft providers decrypts in two steps. The encrypted password is actually a Base64 conversion of encrypted data. So first it converts it back from Base64 and then calls DecryptPassword method. I just did the easiest thing. Copied the code from Microsoft implementation, removed all the checks it was doing and then used it. Following class is an example of a class derived form SqlMembershipProvider with a method that just returns me password in clear text for a given encrypted password.

namespace MembershipPasswordRecover
{
    public class NetFourMembershipProvider : SqlMembershipProvider
    {
        public string GetClearTextPassword(string encryptedPwd)
        {
            byte[] encodedPassword = Convert.FromBase64String(encryptedPwd);
            byte[] bytes = this.DecryptPassword(encodedPassword);
            if (bytes == null)
            {
                return null;
            }
            return Encoding.Unicode.GetString(bytes, 0x10, bytes.Length - 0x10);

        }
    }
}

static void Main(string[] args)
{
    var passwordManager = new NetFourMembershipProvider();
    var clearPWd = passwordManager.GetClearTextPassword("encryptedpasswordhere");
    Console.WriteLine(clearPWd);
}

Configuration of your recovery application

If you are putting this password decryption code in a separate application, then you have to ensure the following things.

  • Create machineKey section in your configuration file under system.web section. It does not matter if you are creating a web application or console application, you always have a application configuration file you can create this entry.
  • You do not have to add an entry for SqlMembershipProvider in configuration file for recovery of the password. But it is good idea to that you copy the same settings from web application into your password decryption application as well.

Here is how app.config file looks in my sample console application. You can see that I do not need a web application to include system.web section in my console application.

<?xml version="1.0"?>
<configuration>
  <system.web>
    <machineKey validationKey="AD3642D1C078D34C05741E5A63514C784......." 
     decryptionKey="F18D8F1FA9F986B26B9F0C8CB4067CAC45E25F4BD......" 
     decryption="3DES" validation="SHA1" />
    <membership defaultProvider="AspNetSqlMembershipProvider" userIsOnlineTimeWindow="15">
      <providers>
        <clear />
        <add name="AspNetSqlMembershipProvider" 
         type="System.Web.Security.SqlMembershipProvider" 
         connectionStringName="SiteSqlServer" enablePasswordRetrieval="true" 
         enablePasswordReset="true" requiresQuestionAndAnswer="false" 
         minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="0" 
         requiresUniqueEmail="false" 
         passwordFormat="Encrypted" 
         applicationName="DotNetNuke" 
         description="Stores and retrieves ......." />
      </providers>
    </membership>
  </system.web>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
</configuration>
 

Views: 6260

Tags:

ASP.Net | DotNetNuke

How to automate login into a DNN portal?

by Naveen 5. April 2011 14:23

In this post I will discuss how to programtically login into a DNN protal. In the past I wrote about how to do this for any ASP.Net in general. Well the basic idea is still the same. You will need to HttpWebRequest object to send a POST request to login page of DNN portal. In the POST request you will provide login credentials, user name and password, through FORM variables or query string variables. And then set the value for __EVENTTARGET variable to ID to login button and you are done. Only thing that is left is to know what are names of keys that corresponds to text boxes for user name and password.

If you are using default Login page of DNN then here are the values of those control IDs.

  • dnn$ctr$Login$Login_DNN$txtUsername: For user name value
  • dnn$ctr$Login$Login_DNN$txtPassword: For password value
  • dnn$ctr$Login$Login_DNN$cmdLogin: For __EVENTTARGET that corresponds to Login button page

Here is code snippet that shows how I had set up my handy method to prepare login data that goes in the POST request.

public static String CreateLoginRequestData()
{
 StringBuilder reqData = new StringBuilder();
 reqData.AppendFormat("{0}={1}","returnurl", "home.aspx");
 reqData.AppendFormat("&{0}={1}", "dnn$ctr$Login$Login_DNN$txtUsername", 
       "myloginname");
 reqData.AppendFormat("&{0}={1}", "dnn$ctr$Login$Login_DNN$txtPassword",
       "mypassword");
 reqData.AppendFormat("&{0}={1}", "__EVENTTARGET",
       "dnn$ctr$Login$Login_DNN$cmdLogin");
 return reqData.ToString();
}

Based on this information, here is code snippet that will send request to login page and then get response.

HttpWebRequest webReq = WebRequest.Create(loginUrl) as HttpWebRequest;
webReq.CookieContainer = cookies;
webReq.AllowAutoRedirect = true;
webReq.Method = "POST";
webReq.ContentType = "application/x-www-form-urlencoded";
byte[] postDataBuffer = 
   Encoding.UTF8.GetBytes(CreateLoginRequestData());
webReq.ContentLength = postDataBuffer.Length;
var strmPostData = webReq.GetRequestStream();
strmPostData.Write(postDataBuffer, 0, postDataBuffer.Length);
strmPostData.Close();
var webResponse = webReq.GetResponse() as HttpWebResponse;
 

Views: 1794

Tags:

DotNetNuke | DotNetNuke | DotNetNuke

How to enable Windows Authentication for DNN

by Naveen 16. December 2010 14:59

Recently I was working on a DNN portal that was restricted to intranet view only because of it being in development stage. We did not want to open the access to publc yet. So I had IP restrictions in place so only internal network access is allowed. When it came time to do the demo for external client, I ad to open up the access to DNN portal for public access. One option you have is to add IP address in access restriction list and allow it to access it. But lot of time you may run into external users who do not have a fixed IP address. And this is more of a case for mobile users where IP addresses change every single time you get disconnected and connected. So the solution you can use is to enable windows authentication on your portal and create an account for user(s) who want to view it from outside the network.

Enabling windows authentication for a DNN portal is no different than doing it for any other ASP.Net application. Your first instinct is that you can change authentication type in web.config of DNN application. No, that is not what you want to do because then you will not be able to use your DNN membership provider that works off of the database. Here are steps that you will need to follow to use mixed Windows and Forms authentication for DNN portal.

  • Start IIS and click on your DNN portal web site and click on Authentication tab or icon.

  • Disable anonymous authentication and Enable windows authentication. On IIS7 and higher, your UI may look as below.

    windows authentication in iis

  • Next step is very important. Since DNN requires full permission set on the physical folder where DNN portal is installed, you will have to make changes to the security on that folder. Give user(s) or group(s) the required rights on the folder. Otherwise you will end up with 401 - Access Denied even after you enter valid windows credentials.

 

Views: 2422

Tags: , , ,

DotNetNuke

How to write custom DNN login module?

by Naveen 28. September 2010 13:54

Download Custom DNN Login Module (43.27 kb)

These days I am working on putting together a DNN site. One of the requirements for the site is to have a login page that is different from what DNN offers out of the box. There are some third party DNN modules available that allow you to customize the look of the login page all together. But my requirements are something that does not fit into any of the modules available out there. So I was on mission to develop my own DNN login module.

If you understand how default login process works and what module gets displayed when you click on login link on the page, then things are very stright forward.

Click on Login link

If you look at the skin that you are using, you will find that it is using Login control that is present in admin>skins folder of your DNN web site folder. Key to the whole process is cmdLogin_Click event handler method that gets called when you click on Login link or button on your page. If you look at the code, you will find the following set of code that is trying to find URL to where request should be redirected.

Response.Redirect(LoginURL(ReturnUrl, (Request.QueryString("override") IsNot Nothing)), True)

This LoginURL method is the one that decides what page will be shown for login. This method is implemented in core DNN library. This is present in DotnetNuke.Common namespace in Globals.vb file. I will not post the code here but I will explain it how this discovery of login page works.

First it is looking for a tab id for login page. This is critical piece that you will need to know. If login as Admin on the site and goto Site Settings menu item, you will find the following set of controls on there under Advanced Settings that allows you to configure some of the key pages of your site. The drop down for Login Page is where you will configure what page to show when user clicks on Login link. If this entry is set to Not specified that means tab id fotr login page in Portal Settings is -1. LoginURL looks at the TabID for login page. If this value is not set meaning the value is -1, then code redirects the users to default DNN login page.

But if you have a page set in Login Page dropdown then LoginURL finds all the modules on that page. Then it iterates over all the modules and check if there is atleeast one module that has frieldly name of Active Login. Following code is from Globals.vb that shows this implementation.

 Public Function ValidateLoginTabID(ByVal tabId As Integer) As Boolean
  Dim hasAccountModule As Boolean = Null.NullBoolean
  For Each objModule As ModuleInfo In New ModuleController().GetTabModules(tabId).Values
  If objModule.ModuleDefinition.FriendlyName = "Account Login" Then
    'We need to ensure that Anonymous Users or All Users have View permissions to the login page
    Dim tab As TabInfo = New TabController().GetTab(tabId, objModule.PortalID, False)
    If TabPermissionController.CanViewPage(tab) Then
      hasAccountModule = True
      Exit For
    End If
  End If
  Next

  Return hasAccountModule
 End Function

Now this is a big problem. This is friendly name of login module that DNN supplies with the framework. So in a way you are forced into using the built in login module. So if you do not have this module on the page, then you will get following error.

You have been redirected to this default Login Page because the Login Page set for this website does not contain a valid DotNetNuke Account Login module, or the permissions have not been set correctly.

Does this mean that you can not build a custom login module. Answer is simple. Yes, you can build your own custom module but you will just need to work around this bug or feature or whatever you want to call it. I will discuss that shortly.

Build Custom DNN Login Module

Now you can go ahead build your custom module that you want to use for login. I will leave those details to you. I have included a sample custom login module that I have put together by copying implementation from DNN login module and tailored it to my needs. Once you have developed the module, add a page into your portal. You can choose the option of not showing in menu. Now goto Admin > Site Settings > Advanced Settings option. Under Page Management section, in Login Page dropdown list, select the page that we just added for login. On this page, add your custom module. Now add Active Login module that ships with DNN framework. Now in settings of this Active Login module, set the option that it is visible to Administrators only. This will ensure that all conditions of login module are satisfied on the page to include your custom login module. And this default login module will stay hidden from your users. And you are all set to go!

Caution

Login module is very crucial module in your portal. If you mess this up, you can make your site unusable because nobody will be able to login including you as super user. Now you can see why DNN has some kind of check on module on the page to decide if they want to allow custom login module or not. Here are some of my suggestions that I follow when doing custom login module development.

  • When starting development and initial testing of the module, do not make changes in site settings to direct login link to your new login page. Initially have your login page visible in menu or access it directly test out your module. Once you are satisified with it, then make site settings change.
  • If you do mess up the module and find your self in situation where you can't login. You have few options.
    • Go into the database and remove the portal settings for Login tab id.
    • If you can't find the entryies in database, then in ValidateLoginTabID method that i mentioned above, force it to return False all the time. This will make sure that you will get redirected to built-in login page.

Sample Custom DNN Login Module

The attached sample is custom DNN login module developed using DNN5.5 libraries in Visual Studio 2010. I have just added bare minimum code to show you how login works. You can extend this module to customize to your need and taste. If you have any quesitons, feel free to contact.

 

Views: 7878

Tags:

DotNetNuke

Smart Phones Poll

What smart phone do you currently own?





Show Results

Month List

Powered by BlogEngine.NET 2.0.0.49
Theme by Naveen Kohli