Tag Archives: Web

Authenticate using Office 365

This is a extension to a previous post about creating a Rails web site that uses external OAuth providers to authenticate users. Until now the Rails template supported Facebook, Twitter, LinkedIn and Google OAuth providers. Lately I have added Office 365 support to the template available on Github. This could be useful for e.g. companies that want to develop web sites for internal applications and allow their internal users to log on using their standard accounts.

Azure portal

  1. Go to portal.azure.com & log in
  2. Expand “more services” and select “active directory”
  3. Choose “applications” and click “add” at the bottom (or click on ”
    Add an application you’re developing” if you are viewing the domain overview)
  4. Give your web application a name
  5. Enter a Sign-On URL and an App ID URL (e.g. http://example.com/users/sign_in). It is not obvious what the App ID URI should be but it seems to work fine to use the same as the Sign-On URL
  6. Configure the app and modify the reply URL to be e.g. http://example.com/users/auth/office365/callback/
  7. Copy the Client ID and add it to the Rails template
  8. Select duration under “keys”, press save and then copy the generated key to the Rails template

Finally, deploy your web site and hopefully it should work.

Create a web site in 53 seconds

N.B. Make sure to read the follow-up to this article that explains how to support Office 365 authentication.

Do you want to create a responsive web site built on Bootstrap with support for Facebook, Twitter, Linkedin and Google+ login in less than a minute? Read on!

I have been a fan of Ruby on Rails since 2007. For those who are not familiar with the framework, Ruby on Rails, or just Rails, is a platform that makes it possible to build web sites in no time at all. But what is even more important is that the focus on convention over configuration, one of the pillars of Rails, makes it simple to extend upon a site later on, even by someone not involved in the original development. Other platforms I have had experience with do not necessarily share the level of adherence to conventions that allow this with the same ease. Or at all.

Most of the web sites I build these days are based on Rails, whether they are small simple concept sites or big complex sites. I create private sites as well as solutions for my work. And most of the time I find myself adding the same set of features to every site. They are responsive and based on Bootstrap, they allow users to log on with OAuth using Devise and they include role based permissions based on CanCan. I got tired to redoing the same steps for every single site and created a template. You can check out a demo version of the output of the template by looking at http://railyard.spotwise.net – please note that due to inactivity the site may need a few seconds to spin up. The purpose of this article is to share this template and how it is used.

To follow the instructions below you need to register at various sites:

  • A git repository. I recommend Bitbucket since creating private repositories is free for personal use. Github is a popular alternative but without an paid account the code will be open. That may or may not be acceptable by you depending on your project.
  • The OAuth providers you want to use (Facebook, Twitter, Linkedin, Google+). My guess is that most already have an account with these. Note that for Google+ the email address of the account will be visible to users logging in so you may want to consider creating an account specifically for your app.
  • Somewhere to host the site. I use Heroku and the example below is based on that. Heroku provides a free tier for small web sites that can then scale with the load. It is certainly possible to host this elsewhere, including on a server of your own. That may be a topic for another article some other time.

Walkthrough

Create Heroku site, DNS name and code repository

First, log onto Heroku and create a new app. You have a choice of hosting the site in the US or in Europe. You can also define a name for the site if you don’t want Heroku to create a name for you. I normally define a name as that makes it easier to tell them apart later on and I also add a suffix to the hostname to identify the location where the site is hosted.

For this walkthrough I will use the name “myweb” as the name of the app. A possible name in Heroku would then be myweb-eu.herokuapp.com. The herokuapp.com part is added by Heroku and is common to all sites hosted there.

If you want to use a custom DNS name now is the time to go into the configuration settings for your domain(s) and create an alias hostname that points to the name provided by Heroku. Please note that the Heroku hostname may not resolve to a static IP address so you want to create an alias for the Heroku hostname, not an A record for the IP address currently used by Heroku for the site.

Again, continuing with the example a record in the DNS zone could be

@example.com
myweb IN CNAME myweb-eu.herokuapp.com.

If you add a custom DNS name you also need to go back into the Heroku settings and add that alias to the list of names for the site. Otherwise, Heroku will not be able to associate incoming requests to the correct site. In Heroku there would thus be both the myweb-eu.herokuapp.com name as well as myweb.example.com.

Finally, you should create a repository for the code. For Bitbucket this is quickly done by clicking on “Create” and giving the repository a name (e.g. myweb). The rest of the information there is optional and pretty self-explanatory.

Create apps within the various OAuth providers

Next step is to select which OAuth providers you want to use. The template currently supports Facebook, Twitter, Linkedin and Google+ and they are selectively enabled by setting the variable at the top of the script to true for the services you want to use. Within the template there are also links to the developer portals of each of the four supported OAuth providers. In addition to these it supports local users. It is easy to configure the script to use any combination of these. You may want to include all of them or perhaps just one. The choice is yours. One thing to keep in mind is that currently the template does not support associating users with one another. If an individual user logs on using different OAuth providers those will be different local accounts. A special caveat is that if those accounts use the same email address it most likely will not work. For this reason you may want to use all of the providers but instead pick based on your app. Twitter does not provide the email address of the user and can safely be combined with any of the others.

For all of the providers you need to provide the URL of the site. This would be the myweb.example.com or, if you do not use a custom hostname, myweb-eu.herokuapp.com. In many cases you can also provide an application icon that is shown to the end user when logging on. Some specific things to keep in mind for each provider are:

  • Facebook: Copy the “app ID” & “app secret” values to the template. Do not forget to publish the app. If you do not do this only yourself (or other developers you designate) will be able to log on. It will work fine for you but when you ask others to try it out they will not be able to log on. In order to publish the app you need to provide a contact email address.
  • Twitter: Copy the “API key” & “API secret” values to the template. Twitter also requires the callback URL to be specified – http://myweb.example.com/users/auth/twitter/callback.
  • Linkedin: Copy the “API key” & “secret key” values to the template. Enable the r_emailaddress and r_basicprofile scopes.
  • Google+: Copy the “client ID” & “client secret” values to the template. Turn on the two APIs “Contact API” and “Google+ API”

Note: The template makes a differentiation between development and production mode. The keys and secrets for the production site must be unique for the individual application. However, if you plan to use this template for multiple apps you can share the development amongst them, that is how I do it. The development keys and secrets needs to be created separately. They would be very similar to the production site but the hostname would be localhost:3000 instead of myweb.example.com.

Create the actual site

OK, so I lied slightly. This has taken way more than 53 seconds. That time was for the actual creation of the site from the template, which is what we are getting to now.

Download the latest template from https://github.com/spotwise/railyard, currently fourteen-twelve.rb. In theory you could use the template directly from GitHub as described in the readme file but you should adapt it to your needs so I recommend you make a local copy, either by cloning the entire project or by downloading just the template.

Then edit the local template file with your favourite editor. If you use a Mac for your development I would personally recommend Textmate.

Some things you want to edit in the file are:

  • The choice of authentication providers
  • The keys and secrets to the OAuth providers used
  • The choice of Bootswatch theme
  • The data model
  • In general, search for the text TODO in the template file and follow the instructions.

    When you have finished updated the template it is time to actually create the site. Just run the command:

    rails new myweb -m

    Depending on your computer and your Internet connection this will take around a minute (or more). If everything worked you should be able to do:

    cd myweb
    rails s

    After that you should be able to open your browser and access http://localhost:3000.

    If you intend to deploy the code to Heroku you should add the gem rails_12factor. You do this by adding this to the file Gemfile in your application root and then run “bundle install”:

    gem 'rails_12factor'

    Deploy

    Now it is time to push the code to the repository as well as to Heroku. First Bitbucket (other repositories would be similar):

    git remote add origin git@bitbucket.org:[username]/myweb.git
    git push -u origin --all
    git push -u origin --tags

    Where [username] is your Bitbucket username. The above commands can be found in the repository web page.

    Then push the code to Heroku to deploy:

    heroku git:remote -a myweb-eu
    git push heroku master

    Finally, with the code on Heroku you need to migrate your database. To do so run the following command from the root folder of your application:

    heroku run rake db:migrate

    Good luck! If you run into problems or need help, please send a tweet to @spotwise.

Your own URL shortener

I use mostly bit.ly for shortening URLs but sometimes you don’t want to be dependent upon a public site, even if it is big and popular. I needed to install a custom URL shortener and this is what I did.

Firstly, my requirements were that it should be lightweight and simple. I didn’t expect that many hits on the URLs and even though I am a big fan of Ruby on Rails the idea of spinning up a Rails site just to dish out a HTTP redirect didn’t sound like a great idea. Instead I went for PHP backed by a MySQL database.

Now, searching for URL shorteners written in PHP results in a large number of hits and it can be pretty daunting to know which to pick. Shortly and Yourls were frequently present in listings of popular shorteners so I decided to setup those and benchmark them. However, the Shortly web site turned out to be unavailable so in the end I settled on just installing Yourls.

Yourls supports both public and private mode of operation. In private mode a password is required to administer it. In my case I wanted to make it simple and allow everyone at the company to manage the URLs but disallow access to the management facilities from the Internet. However, Internet users still need to be able to resolve the URLs. I solved this via conditional rewrites in the Apache configuration, like so:

	Alias /s/ "/srv/www/shortener/"
	RewriteCond %{REQUEST_URI} ^/s/admin
	RewriteCond %{REMOTE_ADDR} !^192\.168\.(\d+)\.(\d+)$
	RewriteRule ^/.*$ - [F]
	RewriteCond %{REQUEST_URI} \+$
	RewriteCond %{REMOTE_ADDR} !^192\.168\.(\d+)\.(\d+)$
	RewriteRule ^/.*$ - [F]
	RewriteCond %{REQUEST_URI} ^/s/[index.php]?$
	RewriteCond %{REMOTE_ADDR} !^192\.168\.(\d+)\.(\d+)$
	RewriteRule ^/.*$ - [F]

The above is from the config file for the corporate web site, lodging the URL shortening under the /s/ subdirectory of the web site. There are three rewrite rules:

  • Preventing access to the admin pages for external clients
  • Preventing access to the link statistics for external clients
  • Preventing access to the link creating page for external clients

By default Yourls will create sequential links starting from one and going up. This makes it trivial to guess other links which is not what I wanted. Fortunately, it turned out to be very simple to create random links by following the instructions found on this page.

I am quite happy with the result. I wish the default web GUI would come with different themes but since it is only used when administering the links it doesn’t really matter. I will continue to use bit.ly but Yourls is definitely a keeper.

Proxy a web site and change the content on the fly

Apache can do just about everything with a bit of configuration. I have used HTTP proxying on a number of occasions to make content from one site appear to come from another site. This can be very handy for sites I host at home where I only have one IP address but two servers and want to host different web sites on the same public IP – and all of them on the standard HTTP port.

However, until recently I hadn’t experienced that Apache can also rewrite the content in the actual response. I was faced with the requirement to change all the URIs in the proxied web site so that they pointed to the new URL. When I first searched the net I found the module mod_proxy_html which sounded like the way forward. In the end I didn’t go that route since I found it overly complex and didn’t transform all instances of the links. Instead, the solution was simple and used another Apache module – mod_substitute.

The following virtual host configuration sets up a proxy so that the site www.one.com is proxied to www.two.com. In addition, any occurrences of www.one.com is changed into www.two.com:


<VirtualHost *>
  ServerAdmin postmaster@two.com
  ServerName www.two.com
  <Proxy *>
    Order deny,allow
  </Proxy>
  ProxyRequests on
  ProxyPass / http://www.one.com/
  ProxyPassReverse / http://www.one.com/
  AddOutputFilterByType SUBSTITUTE text/html
  Substitute "s|www.one.com|www.two.com|n"
</VirtualHost>

Combine subversion, WebSVN and a web page in one Apache site

In my last post I wrote about how to get libapache_mod_auth_pam to play nicely with Apache2. This post is about putting it all together, complete with WebSVN and a default web page so that one can write an introductory text to the users using the site.

Getting subversion up and running on Apache was explained in the last post. The problem with that, however, is that the Location directive means that all content on the site is directed to dav_svn. Hence, it is not possible to access an index.html page in the root, nor the /websvn folder. If you try, you will just get the message “Could not open the requested SVN filesystem”.

Of course, the simple solution to this would be to put the dav_svn module one folder down in the site structure (e.g. http://svn.example.com/repositories/<repository>) by changing the Location directive to <Location /repositories/>. But that is ugly.

I assume there are many ways to solve this but here is how I did it.

  1. First, create two sites – svn.example.com and websvn.example.com (or whatever you want to call them).
  2. Configure the site svn.example.com as explained in the previous post
  3. Configure the site websvn.example.com as you would any other static site, adding a index.html file in the root with whatever content you want to have there
  4. Now, before the Location directive in the svn.example.com site definition, add the following:

  5. RewriteEngine on
    RewriteRule ^/$ index.html [R]
    ProxyPass /websvn/ http://websvn.example.com/websvn/
    ProxyPassReverse /websvn/ http://svn.example.com/websvn/
    ProxyPass /index.html http://websvn.example.com/index.html

  6. Finally, you may also want to add SSL support for the svn.example.com site but I won’t go into that here

To make this work, a couple of Apache2 modules must be enabled, namely: proxy, proxy_http and rewrite.

What the above does is that it rewrites accesses to the root URL / to /index.html. Then, all requests to either /index.html or /websvn are proxied to the other site (which does not have dav_svn enabled so they work fine there).

With everything in place, you should be able to access http://svn.example.com for the index.html page, http://svn.example.com/websvn for the WebSVN interface to the repositories – and anything else for the real repositories.

A prettier solution would be if the Location directive for Apache supported negated regular expressions but I have come to the conclusion that it doesn’t – at least not the version I am using (2.2.8).