Google Analytics

Showing posts with label WCF. Show all posts
Showing posts with label WCF. Show all posts

Thursday, August 27, 2015

Some Assembly Required

I thought I would post this answer out there to hopefully save some people the hassle I just had in trying to troubleshoot a "Could not load file or assembly" error, for in my particular case I have not seen the same solution posted out there yet.

My case is this - I was getting an error trying to open a locally installed web service. The "warning" (though it really should show as an error, imho) showing up in my event log was this:

Could not load file or assembly 'System.Data.SQLite' or one of its dependencies. An attempt was made to load a program with an incorrect format.

The "incorrect format" part usually has to do with having an x86 version of the DLL in question rather than an x64 version, and SQLite is one of those where it has a different library for each platform. I had installed the x64 version of the service, so I checked that it was also installing the x64 version of the SQLite DLL, which it was. I was perplexed. Everything I was Googling made me think that somehow it was loading up the 32-bit version somehow. Finally I had my aha moment.

A couple days back, while trying to build and run this same service, the configuration was such that only the 32-bit version of the service would build. So, at the time, I changed the Application Pool that it ran under to allow 32-bit applications. That changes the Application Pool to use WoW64, the Windows 32-bit emulator. So, the Application Pool thought it needed the x86 SQLite DLL. Once I changed the Application Pool to not allow 32-bit applications everything ran smoothly once again.

Monday, January 19, 2015

Creating a Local Windows Group on Install

One of the recent Installer/Wix issues that needed to be addressed in our product was to automatically create a Windows group on install. Our installer creates and starts a number of Windows services that are run as a particular user with the appropriate permissions. Currently, whomever is installing the product must create the local group, create the user account to run the services and add the user to the local group before running our installer. In order to count down on the tasks the user must do manually, we added a story to both create the local group and user on install, and I first took to doing a spike solution to create the group.

Doing a spike allowed me to isolate the action needed to just creating the group. Our installer is currently made up of several Wix libraries, approximately a dozen Wix source files, and a number of custom actions. I wasn't confident about finding just the right place to add the group before I even understood how to do it. Also, the spike allowed me to quickly run the install and uninstall without going through all the other actions our current installer does.

My hope was that I could do it fairly simply with Wix or with the Wix Utilities extension. The utilities extension does provide a group element; however, "This element is not capable of creating new groups but can be used to add new or existing users to an existing group." Luckily a Google search indicated that someone had already done the work to create the necessary custom actions to do this. Msiext (http://dblock.github.io/msiext/) contains a UserPrivileges extension along with a number of other Wix extensions which I wish I had known about before. The download includes runnable demos, but there isn't much in the way of documentation. Ergo, I'm writing this blog post rather than simply pointing you to some documentation there.

So I got the latest msiext download. I created a console app as my spike and added a Wix Setup project to the solution. To the setup project I added a reference to the WixUserPrivilegesExtension DLL in the msiext package. This gives access to the LocalGroup element:

<UserPrivileges:LocalGroup Id="DemoLocalGroup1" Name="DemoLocalGroup1"
Description="Demo local group 1 for a spike." CheckIfExists="yes"
CreateOnInstall="yes" DeleteOnUnInstall="yes">
</UserPrivileges:LocalGroup>

The explanation is pretty straight-forward. the Id is the unique element id, Name is the name of the group and description is what appears in the description when you Manage Groups in Windows. CheckIfExists will prevent it from re-creating the group if the group already exists. CreateOnInstall creates the group on install and DeleteOnUnInstall will delete the group on uninstall. These can be changed if, for example your application creates the groups itself and all you want to do is delete it on uninstall, or if you want to leave the group unchanged even if the user chooses to uninstall. Like I said, pretty straight-forward.

My entire Product.wxs looks like so:


xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
     xmlns:UserPrivileges="http://schemas.appsecinc.com/wix/UserPrivilegesExtension">
    <Product Id="*" Name="SetupProject1" Language="1033" Version="1.0.0.0" Manufacturer="PlutoTech" UpgradeCode="5eec8bc9-ee30-451b-b3c2-fd4ce78bf277">
        <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
        <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
        <MediaTemplate />
        <Feature Id="ProductFeature" Title="SetupProject1" Level="1">
            <ComponentGroupRef Id="ProductComponents" />
        </Feature>
    </Product>

    <Fragment>
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
                <Directory Id="INSTALLFOLDER" Name="SetupProject1" />
            </Directory>
        </Directory>
    </Fragment>
 
    <Fragment>
        <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
            <Component Id="LocalUserGroupDemo1" Guid="YOUR-GUID-HERE">
                <UserPrivileges:LocalGroup Id="DemoLocalGroup1" Name="DemoLocalGroup1"
                    Description="Demo local group 1 for a spike." CheckIfExists="yes"
                    CreateOnInstall="yes" DeleteOnUnInstall="yes">
                </UserPrivileges:LocalGroup>
                <File Id="File.MyService" KeyPath="yes" Source="$(var.AddLocalGroupSpike.TargetPath)" />
            </Component>
        </ComponentGroup>
    </Fragment>
</Wix>

Note that the INSTALLFOLDER cannot be the keypath for the component. In this case it is actually the executable, Id="File.MyService. In our actual installer, the component that creates the necessary groups is separate from any other files, but the component group it belongs to is associated with the TARGETDIR directory.

Thursday, June 14, 2012

WCF Federated Security


Service security has been an ongoing issue with these products that we currently have in development. Each inidividual product we have created thus far generally has its own mechanism for authorization and authentication, though we definitely reuse certain components and libraries between them. For some time our vision has been to have a composite application using WPF with Prism with calls to different WCF services. In brief the architecture would be a basic application shell with some intrinsic administration functionality like user management, and each component of our election management system would be a plug-in module to the shell at the interface level along with its own WCF service at the server level. A further issue is whether each module would have its own database or there be a joint election database or series of common databases for all modules. That issue is another series of blog posts in itself.

The issue we are tackling is with shared security amongst the different modules. Once a user logs in to the application, those credentials need to be verified or otherwise trusted by each plug-in's respective service. To date, we have bounced around a number of ideas about how to do this having come to no real decision yet. I would like to explore a federated security model, since it seems to lend itself to this specific issue.
I want to create a spike solution with our basic architecture -- a shell with a couple plug-ins each with a backing WCF service -- and run through different security scenarios with it. I'm starting with reading the MSDN articles on the subject here: http://msdn.microsoft.com/en-us/library/ms731161.aspx.

So after reviewing the articles there, I have a bit of a chicken-egg problem in creating my spike solution. What component do I try to tackle first? I think that I may start with the Security Token Service, since it seems the other services and client will rely on that existing. Ah - there is a Federation Sample here: http://msdn.microsoft.com/en-us/library/aa355045.aspx. Looks simple enough. I'll try and implement my own solution as described above, but think I just need the one STS.