Consuming RabbitMQ Messages in ASP.NET MVC

TLDR: You want to set up RabbitMQ in an ASP.NET process to persistently consume messages, and do something (like dump them to a database). This has to be independent of the life-cycle of an ASP.NET/MVC (W3WP.exe) worker process.

I experimented with several variations of the Hello World C# RabbitMQ tutorial. In the end, two changes made this work, and persistently consume messages, from my ASP.NET MVC application:

  • I kept static references to IConnection and IModel
  • I removed the using statements around the connection and model

What’s confusing is that static variables with using statements doesn’t work; it consumes all messages, but only displays the oldest one.

Regardless, the set of changes is relatively small. Here’s what I did in Global.asax.cs:

  • Declare IConnection and IModel static variables in your MvcApplication class
  • On Application_Start, paste the entire sample; make sure you change the use of connection and channel to use your static versions, and not to be in using statements
  • Add an Application_End method that closes the channel and connection

Below is a typical freshly-generated Global.asax.cs for MVC5, with these changes:

public class MvcApplication : System.Web.HttpApplication
    {
        private static IConnection connection;
        private static IModel channel;

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            this.SetupRabbitMqSubscriber();
        }

        protected void Application_End()
        {
            channel.Close(200, "Goodbye!");
            connection.Close();
        }

        private void SetupRabbitMqSubscriber()
        {
            var factory = new ConnectionFactory() { HostName = "localhost" };
            connection = factory.CreateConnection();
            channel = connection.CreateModel();
            channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null);

            var consumer = new EventingBasicConsumer(channel);
            consumer.Received += (model, ea) =>
            {
                var body = ea.Body;
                var message = Encoding.UTF8.GetString(body);
                // Display message
            };
            channel.BasicConsume(queue: "hello", noAck: true, consumer: consumer);
        }
    }

This essentially keeps a persistent connection open to the RabbitMQ server, so long as the w3wp.exe process survives.

Posted in Libraries, Web | Tagged , | Leave a comment

How to Subclass .NET Classes from IronPython

IronPython is awesome. The recent revival of the new IronPython 3 project caused me to look again at IronPython (2.7).

What if you created a base class in .NET and you want to subclass it in your IronPython code?

For my Prototype MonoGame game, I created an AbstractScene class representing a scene. I want to write all the logic for it in Python, which means creating a subclass like CoreGameScene. I want to write Python code like this:

class CoreGameScene(AbstractScene):
    # ... implementation
    # ... calls to super(...)

To get IronPython to understand what AbstractScene is, I need to do two things:

First, I need to tell the runtime to load the types in my .NET assembly. (This forum message from 2009 suggests that this works better than using SetVariable to pass down a specific type.)

That code looks quite simple:

var engine = Python.CreateEngine();
engine.Runtime.LoadAssembly(typeof(AbstractScene).Asseembly);

Then, to use it in Python, I just need to fully qualify the class package structure (first line in this code block):

from DeenGames.InfiniteArpg.Scenes import AbstractScene

class CoreGameScene(AbstractScene):
    def __init__(self, graphicsDevice):
        super(CoreGameScene, self).__init__()

Everything works! I can create an instance of CoreGameScene and see the calls to the AbstractScene constructor (which takes a GraphcisDevice parameter).

Posted in Libraries, Wndows Forms | Tagged | Leave a comment

Changing the Login URL from login.aspx on ASP.NET MVC with Forms Authentication

In a previous post, we talked about adding forms authentication to an ASP.NET project backed by Web API.

One of the caveats of this setup is that if you apply the [Authorize] attribute to a controller or method, and the user is not authenticated, they get redirected to ~/login.aspx. This obviously doesn’t do well in an ASP.NET MVC context.

The fix is fairly trivial: open up web.config and change <authentication mode="Forms"> to this block:

<authentication mode="Forms">
  <forms loginUrl="~/Account/LogOn" />
</authentication>

This will change the URL to ~/Account/LogOn. This apparently didn’t work well in previous versions of ASP.NET MVC and required an additional appSetting, but it seems to work fine in MVC5.

Posted in Libraries, Web | Tagged | Leave a comment

Authenticating Against Web API from ASP.NET MVC

In a previous post, we talked about setting up ASP.NET MVC and Web API to accept forms authentication.

With this structure in place, your MVC front-end can make Web API calls. The question is, how do you authenticate? What cookies do you need to pass around?

There are actually two sets of cookies involved:

  • The MVC side has its own authentication cookies (.ASPXAUTH)
  • The Web API returns two cookies: an empty .AspNet.ExternalCookie one, and a .AspNet.ApplicationCookie one.

It’s this latter cookie that you need to pass to your API client to authenticate any subsequent calls. When you receive them, you need to store them somewhere (I used the session).

Here’s the call to log in to the API:

var client = new RestClient("/api");
var request = new RestRequest("Account/LogIn", Method.POST);
request.AddObjec(loginViewModel);

var response = client.Execute(request)

if (response.StatusCode == HttpStatusCode.OK)
{
    Session["AuthCookies"] = response.Cookies;
    FormsAuthentication.SetAuthCookie(model.Email, model.RememberMe);
    HttpContext.User = new GenericPrincipal(new GenericIdentity(model.Email), null);
    return Redirect("~/");
}
else
{
    ModelState.AddModelError("", "Invalid login attempt.");
    return View(model);
}

Notice we’re saving the response’s cookies in Session["AuthCookies"].

Once we have those, we pass them to any subsequent API calls:

var client = new RestClient("/api");

var cookies = Session["AuthCookies"] as IList<RestResponseCookie>;
if (cookies != null)
{
    client.CookieContainer = new System.Net.CookieContainer();

    foreach (var cookie in cookies)
    {
        client.CookieContainer.Add(new System.Net.Cookie(cookie.Name, cookie.Value, cookie.Path, cookie.Domain));
    }
}

// build a request object
var response = client.Execute(request);

I don’t think storing Web API authentication cookies in the session is a good idea (it opens you up to session hijacking). If you know a more secure way to manage the authentication cookies, please share it in a comment.

Posted in Libraries, Web | Tagged , | Leave a comment

Running FluentMigrator Migrations at Runtime

FluentMigrator’s Migrations Runners wiki page doesn’t mention any way of running migrations through code.

Why might you want to do this? Because your application is in the hands of users, or ops teams, or someone who needs to run the migrations. Or, because you want to auto-run migrations, say, on start-up.

It’s not a trivial amount of work, but it’s achievable. The core logic is in this MigrationsWrapper class I wrote:

public class MigrationsWrapper
    {
        private static Assembly migrationsAssembly = Assembly.Load("...");

        private string connectionString;
        private Action<string> logMethod = Console.WriteLine;

        public MigrationsWrapper(string connectionString, Action<string> logMethod = null)
        {
            this.connectionString = connectionString;
            if (logMethod != null)
            {
                this.logMethod = logMethod;
            }
        }

        private MigrationRunner GetMigrator()
        {
            var announcer = new TextWriterAnnouncer(s => logMethod.Invoke(s));

            var migrationContext = new RunnerContext(announcer);
            var options = new MigrationOptions { PreviewOnly = false, Timeout = 60 };
            var factory = new FluentMigrator.Runner.Processors.SqlServer.SqlServer2008ProcessorFactory();
            var processor = factory.Create(this.connectionString, announcer, options);
            var runner = new MigrationRunner(migrationsAssembly, migrationContext, processor);

            return runner;
        }

        public void MigrateToLatestVersion()
        {
            var runner = GetMigrator();
            runner.MigrateUp(LatestVersionNumber);
        }

        public void MigrateToVersion(int version)
        {
            var runner = GetMigrator();

            long currentVersion = CurrentVersionNumber;

            if (currentVersion < version)
            {
                runner.MigrateUp(version);
            }
            else if (currentVersion > version)
            {
                runner.MigrateDown(version);
            }
        }

        public long LatestVersionNumber
        {
            get
            {
                long toReturn = 0;
                // Look through all types
                foreach (Type t in migrationsAssembly.GetTypes())
                {
                    // Get all the types with MigrationAttribute (object[] because it can have multiple Migration attributes)
                    object[] attributes = t.GetCustomAttributes(typeof(MigrationAttribute), true);
                    if (attributes.Length > 0)
                    {
                        // Get the max of (current max, max version specified in this Type's Migration attributes)
                        toReturn = Math.Max(toReturn, attributes.Max(o => (o as MigrationAttribute).Version));
                    }
                }

                return toReturn;
            }
        }

        public long CurrentVersionNumber
        {
            get
            {
                long toReturn = 0;

                using (var conn = new SqlConnection(this.connectionString))
                {
                    conn.Open();

                    try
                    {
                        toReturn = conn.Query<long>("SELECT MAX(Version) FROM VersionInfo").First();
                    }
                    catch (SqlException)
                    {
                        toReturn = 0;
                    }
                }
                return toReturn;
            }
        }

        private class MigrationOptions : IMigrationProcessorOptions
        {
            public bool PreviewOnly { get; set; }
            public string ProviderSwitches { get; set; }
            public int Timeout { get; set; }
        }
    }

To run it, you just call new MigrationsWrapper(connectionString).MigrateToLatestVersion() and you’re done.

By default, it prints out messages to Console.WriteLine. Instead, you can pass in whatever Action<string> method you want.

To get this to compile in your project:

Resolve compilation errors with CTRL + . until everything compiles, and you’re done.

The core is the creation of a new MigrationRunner instance (from the FluentMigator.Runners package, and creating all required objects for settings.

MigrationsWrapper also uses some reflection trickery to get the latest version number.

Also, make sure your migrations classes are public. If they’re not, the migrations runner won’t find and run them.

Posted in Libraries, Web, Wndows Forms | Tagged , | Leave a comment

Adding Forms Authentication to Web API

When you create a new Web API project, it grafts the API onto the existing web project. This can prove sub-optimal in cases where you want everything (including Forms authentication) to call into the API.

Thankfully, it’s fairly easy to separate out the Web API code into a separate project, and then graft the authentication mechanism into it. (Ask yourself first if you really want to do this; the Web API starter project includes external authentication only by default).

Whether you want to use forms authentication on a single project with both the API and MVC code, or on a Web API project that’s separate from the MVC project, the steps are similar.

Caveat: I derived these changes by reverse-engineering an MVC5 application with Web API 2 — I started copying over code, then dependent code, and then adding missing config. These steps may change with newer versions of Web API.

Change the Authentication in WebApiConfig

Replace this block:

// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

With this line:

config.Filters.Add(new AuthorizeAttribute());

Add the ApplicationSignInManager to IdentityConfig

Copy/paste the ApplicationSignInManager class from your MVC project into App_Start/IdentityConfig.cs. Here’s how that looks today:

    // Configure the application sign-in manager which is used in this application.
    public class ApplicationSignInManager : SignInManager<ApplicationUser, string>
    {
        public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager)
            : base(userManager, authenticationManager)
        {
        }

        public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
        {
            return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);
        }

        public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context)
        {
            return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication);
        }
    }

Enable Cookie-Based Authentication

Open up App_Start/Startup.Auth.cs and replace this line:

app.UseCookieAuthentication(new CookieAuthenticationOptions());

With this block:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/Account/Login"),
    Provider = new CookieAuthenticationProvider
    {
        // Enables the application to validate the security stamp when the user logs in.
        // This is a security feature which is used when you change a password or add an external login to your account.  
        OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
            validateInterval: TimeSpan.FromMinutes(30),
            regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
    }
});

Modify ApplicationUser’s GenerateUserIdentityAsync method

Open up Models/IdentityModel.cs and add a second version of GenerateUserIdentityAsync that takes only a single input:

public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
    return await this.GenerateUserIdentityAsync(manager, DefaultAuthenticationTypes.ApplicationCookie);
}

Add a View Model

Create a LoginViewModel in Models/AccountViewModels.cs:

public class LoginViewModel
{
    public string Email { get; set; }
    public string Password { get; set; }
    public bool RememberMe { get; set; }
}

Add a Login Method to your AccountController

Now, the bulk of the work: create the actual LogIn method on your AccountController. Conceptually, you need to add the SignInManager, and then wire up the call (just like the MVC project does).

First, add the SignInManager and wrapper property:

private ApplicationSignInManager _signInManager;

// ...

protected ApplicationSignInManager SignInManager
{
    get
    {
        return _signInManager ?? HttpContext.Current.GetOwinContext().Get<ApplicationSignInManager>();
    }
    private set
    {
        _signInManager = value;
    }
}

Next, update the constructor to take in this additional dependency (constructor injection):

public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager,
    ISecureDataFormat<AuthenticationTicket> accessTokenFormat)
{
    UserManager = userManager;
    SignInManager = signInManager;
    AccessTokenFormat = accessTokenFormat;
}

I think this step is optional. There’s no code to call the constructor directly, and I didn’t see any dependency injection configuration. If you look closely at the SignInManager property from the last call, you’ll notice that it initializes itself.

Finally, wire up the LogIn call:

// POST Account/Login
[AllowAnonymous]
[Route("LogIn")]
public async Task<IHttpActionResult> LogIn(LoginViewModel model)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    var user = UserManager.FindByEmail(model.Email);

    // This doesn't count login failures towards account lockout
    // To enable password failures to trigger account lockout, change to shouldLockout: true
    var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
    if (result == SignInStatus.Success)
    {
        return Ok();
    }
    else
    {
        return BadRequest(ModelState);
    }
}

And that’s it! Now, you can log in (through code, or with an HTTP client) by POSTing your request. (eg. you can use RestSharp to create a client, POST a register method, and then POST a login call).

If you want to wire up your MVC5 project to use your new method, you need to make a few more changes.

Renable Forms Authentication in Web.config

Replace <authentication mode="None" /> with:

<authentication mode="Forms">
  <forms loginUrl="~/Account/LogOn" />
</authentication>

This re-enables forms authentication, and when an unauthorized user tries to access an authentication-required method, redirects them to /Account/LogOn instead of login.aspx.

If it exists, remove this block:

<system.webServer>
    <modules>
      <remove name="FormsAuthentication" />
    </modules>
  </system.webServer>

Call the API in the AccountController

Modify your Login method in AccountController to call the Web API method. Here’s how that looks with RestSharp:

//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{

    var restClient = new RestClient(API base URL, possibly from web.config);
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    var request = new RestRequest("Account/Login", Method.POST);

    request.AddObject(model);
    var response = restClient.Execute(request);

    if (response.StatusCode == HttpStatusCode.OK)
    {
        FormsAuthentication.SetAuthCookie(model.Email, model.RememberMe);
        HttpContext.User = new GenericPrincipal(new GenericIdentity(model.Email), null);
        return RedirectToLocal(returnUrl);
    }
    else
    {
        ModelState.AddModelError("", "Invalid login attempt.");
        return View(model);
    }
}

With that, you can log in through your web app. It calls the Web API, gets the cookies back, and stores it so that subsequent calls use the same authentication session.

This also populates the value of Request.IsAuthenticated and HttpContext.Current.User.Identity with your current user.

This code follows existing conventions from the MVC starter code (eg. wrapping the SignInManager in a property, using underscores for member variable names, etc.) so adopt it to whatever style suits you.

Posted in Core .NET, Web | Tagged , | Leave a comment

Creating Cross-Platform MonoGame projects

As of the MonoGame 3.5 release, circa mid-2016, there’s a lot of confusion around how to create a single, cross-platform MonoGame solution that gives you executables for Windows, Linux, and Mac.

Do you need one solution per platform (eg. a Windows project, a Linux project, and a core/shared project)? Do you need to use PCL? Do you need to maintain two solutions, and add code as references? Do you need to use ProtoBuild or other tools?

The answer is pretty simple: MonoGame 3.5 introduced something called the “DesktopGL” project, which is cross-platform. You get one executable out of it, which runs on both Linux and Windows. On Linux/Mac, it uses Mono.

If you install MonoDevelop (on Linux), you won’t see a DesktopGL project template; only a “MonoGame Cross Platform Desktop Project” template. This is, indeed, what you want.

Posted in Libraries | Tagged , | Leave a comment

Defeating Memory Editors with Moving Values

Many years ago, I inquired on the GameDev StackExchange site about how to stop players from using memory editors to cheat. While slightly controversial, I still maintain that this is a fun academic exercise.

Recently, I revisited this concept. After lots of experimentation with a simple game (press a key to fight, player and monster both decrease in health by a random amount), I arrived at a working solution based on my initial concept.

Memory editors work because programs store (integer) values in the same location in memory, for as long as the game runs. C# applications also exhibit this behaviour. Memory editors exploit this, by allowing the user to scan for a specific value, or a changed (eg. decreased value).

Some anti-cheat mechanisms work around this by masking the value (eg. storing it as twos-complement or inverted, or added/subtracted to a random value), or by never displaying the original value.

My solution involved actually moving the object to a new location. In .NET, this means re-creating the original object’s value, in a new object.

What if you read this value in your game loop, at 60FPS, and each read results in a write? That may lead to poor performance. Instead, the value only changes on each write operation.

Some code:

class MovingValue<T> {
  private Box<T> box;

  public MovingValue(T value)
  {
      this.box = new Box<T>(value);
  }

  public T CurrentValue
  {
      get { return this.box.Value; }
      set { this.box = new Box<T>(value); }
  }

  class Box<T>
  {
      public T Value { get; set; }

      public Box(T value) { this.Value = value; }
  }
}

I chose the names MovingValue to indicate that the value stored moves, and Box because it uses a concept similar to boxing/unboxing.

The value stored changes on each write operation, and you can always get the current value. To use it, you change this:

class Player {
  private int health = 30;

  public int Health { 
    get { return this.health; }
    set { this.health = value;
  }

  public void GetHurt(int damage) {
    health -= damage;
  }
}

To this:

class Player {
  private MovingValue<int> health = new MovingValue<int>(30);

  public int Health { 
    get { return this.health.Value; }
    set { this.health.Value = value;
  }

  public void GetHurt(int damage) {
    health -= damage;
  }
}

I tested this with the ArtMoney memory editor. The original health int address is easy to locate/freeze, while the MovingValue address can’t be pinned down, even with multiple rounds of scanning.

This design also doesn’t suffer from any type of concurrency issues or race-conditions (which it would if you moved the value with, say, a timer).

As a final caveat, I would be weary of:

  • Updating this value frequently (like every render/update tick), because it allocates a new object every single write.
  • Updating this value with a very large object, that has multiple fields/sub-fields (perhaps with collections). If you update frequently, this can compound problems.
Posted in Core .NET | Tagged | Leave a comment

Generating a Random DateTime in a Range in SQL Server

There are lots of answers on Stack Overflow about generating a random date within a range. But what if you wanted a random date, and a random time?

I ended up with this snippet:

-- Change these
DECLARE @date_from AS DATETIME = '2015-05-01'
DECLARE @date_to AS DATETIME = '2015-05-31'

-- Don't change this
DECLARE @days_diff AS INT = cast(@date_to - @date_from AS INT)

SELECT @date_from +
DATEADD(second, ABS(CHECKSUM(newid()) % 60), 0) + -- random seconds
DATEADD(minute, ABS(CHECKSUM(newid()) % 60), 0) + -- random minutes
DATEADD(hour, ABS(CHECKSUM(newid()) % 24), 0) + -- random hours
DATEADD(day, ABS(CHECKSUM(newid()) % @days_diff), 0) -- random days

This gives you granularity up to the second in terms of randomness. (For some reason, simply using DATEADD with a mod of 60 * 60 * 24 * @days_diff results in a loss of hour/minute/second precision.)

If you want an explanation, ABS(CHECKSUM(newid()) is an approximation of a random number generator in SQL, for when you want a different random value per-row (RAND gives you the same value for all rows in the query). By guaranteeing that it’s a positive value, you can modulo it to get a random number in a range.

Posted in Tools | Tagged | Leave a comment

Mocking Base Class Methods with Moq

Moq does allow you to mock base class methods, via the use of the Moq.Protected namespace. You can read about it here.

Imagine you have the following scenario:


class Animal {
private int timesTalked = 0;
public void Talk() {
timesTalked++;
}
}

class Cat {
public void Talk() {
base.Talk();
Console.WriteLine("meow!");
}
}

class CatTest {
public void TalkDoesntThrow() {
var c = new Moq().Setup(c => c.Talk()) ... // Cat.Talk

In this case, you want to test the Cat.Talk method by mocking out the base class method. How can you do this?

At first glance, you can’t, because the signatures match. But, if you can make your base class method protected instead, that gives you breathing room:


class Animal {
protected void Talk() { .. }
}

class CatTest {
public void TalkDoesntThrow() {
var c = new Mock();
c.Protected().Setup("Talk") ... // Animal.Talk
}

If this doesn’t work, you need to change one of the method signatures, like so:


class Cat {
public void Talk(string message) { ... }

The final caveat I noticed is that the mocking is sensitive to the use of the base keyword. It seems like the CLR knows the actual base type and calls that, instead of the one derived from Moq.

That is, in our Cat class, we call base.Talk. Instead of that, we should just invoke Talk.

This affects the runtime binding, since Moq dynamically subclasses our mocked classes.

Posted in Libraries, Web, Wndows Forms, WPF | Tagged | Leave a comment