I amended your code to use an control from the extension library rather than the dijit.Dialog dojotype.
The dialogs do not work in the same way as I expected, and I don't understand why.
With the dijit.Dialog, there is one POST (as expected), whereas with the dialog contol there are always two POSTs (the first to names.nsf as expected, the second to refresh the dialog).
If the login is successful then it doesn't matter because the page is redirected to the successful login url. If the login failed, then the user doesn't see the failure reason.
alert(1)
dojo.xhrPost({
url: loginurl,
handleAs: 'text',
content: {'username' : dojo.byId('#{id:username}').value, 'password' : dojo.byId('#{id:password}').value},
load : function(response, data) {
alert(2)
....
Using firebug I can see that both POSTs occur between the two alerts
I was wondering if you had tried to get use a dialog control rather then dijit.Dialog, and if so had had sucess with it