Last year I had a series of things I learned in 2012. I decided not to continue the monthly posts this year but was still keeping track of things as I came across them. Here’s a short list from the year.
- SAML 2.0 (utilizing OneLogin‘s ruby-saml gem)
- Salesforce Development (APEX, SOQL, REST/SOAP API, Chatter, Single Sign-On, etc.)
- Wrote soapforce gem based on Savon2 and restforce gem
- EngineYard – Excellent PaaS Provider
- Learned a number of things about MySQL and Postgres that I didn’t know before.
- Numerous remote APIs for integrating with service providers (Box, DocuSign, EasyPDFCloud, ConvertApi, DocRaptor)
- CSS content property
- HTML5 download attribute
- HTML5 Demos – contenteditable, storage, history
- CSS: user-select: none;
- $x(“//input[@type=’checkbox’]”) – Locate elements with XPath in FireBug
- IE has a maximum number of style tags and CSS rules it will load.
- @cc_on – IE specific conditional property
- rake db:migrate:status
- Tire gem for elasticsearch
- Rails Model.update_all
- rails runner
- guard (jasmine, rspec, rails, cucumber, etc)
- gems: bullet, mailcatcher, quiet_assets, better_errors
- bundle outdated
- Gemfile: gem ‘name’, github: ‘user/repo’
- ActiveRecord Batches
- requestb.in – Great debugging tool for http requests
- base64decode.org & base64encode.org
- cssclean.com & codebeautifier.com
- Freenode web chat
- Crocodoc – HTML5 Document Viewer (Acquired by Box May 2013)
- CMD+L takes you to address bar in Google Chrome on OSX
- Option+Enter to duplicate a tab in Google Chrome on OSX
- Generate the public portion of the key: ssh-keygen -y -f <name of key>
- Email notes to Evernote
- Argument Dependent Lookup (ADL) (C++)
- Dump/Load over SSH: mysqldump <dbname> | ssh <new_db_master_host> “mysql <dbname>”
- Made my first strawberry rhubarb pie. Rhubarb was ruled (by a New York court) to be a fruit in 1947 although technically a vegetable.
- Learned a lot about baseball after becoming a St Louis Cardinals fan this year.
- Bought my first motorcycle and have learned a lot about riding and taking care of a bike.
- Learned a bit about Seattle during my 6 week stay.
- Learned how to make a killer Egg Nog!
- Learned how to make soft pretzels
I recently introduced myself to SAML, Security Assertion Markup Language, and thought I’d pass along what I learned. These two [1 and 2] YouTube videos by PingIdentity were a helpful introduction to SAML from a high level view.
The parties involved:
- Identity Provider (IdP) – OneLogin, Salesforce, Okta, etc.
- Service Provider (SP) – TinderBox, Box, Concur, etc.
- You (Me)
To see the following steps in action, check out this great walk through with more detail about the messages.
Step 1: Unauthenticated user (You) tries to access a hosted service (SP).
Step 2: SP generates an Authentication Request (AuthnRequest)[gist https://gist.github.com/jheth/7961957]
Step 3: SP submits request to IdP (HTTP Redirect)
Step 4: IdP handles SAML Request and Authenticates User
In most cases the authentication step is done through the typical username/password login form. Since login was initiated with a SAML Request the IdP knows it must send the desired SAML Response.
Step 5: IdP generates SAML Response XML Document[gist https://gist.github.com/jheth/7962107]
Step 6: IdP submits response to SP
POST https//www.hostedservice.com/sso/saml/acs SAMLResponse: [base64 encoded XML]
Step 7: SP consumes and validates assertion
The XML document is checked for validity, which includes the conditions NotBefore and NotOnOrAfter (timestamps) and AudienceRestriction. Note: Watch out for clock-drift with the timestamp attributes, you may need to account for slight variations.
Step 8: SP grants or denies access based on the response.
Once determined to be a valid request your application is responsible for logging the user in without prompting for additional information. Once authenticated the user is redirected to the resource they originally requested.
As you can see above, there are specific URLs used by both the IdP and SP during the request/response phase. This is where configuration and an exchange of information is necessary and where some of the security of SAML comes into play.
The SP at a minimum needs to know the following, which is provided by your IdP when you register with them.
- IdP SSO Target URL: https://app.onelogin.com/trust/saml2/http-post/sso/XXXXXX
- IdP Certificate Fingerprint (SHA-1): 8D:96:A0:99:BC:11:F7:2D:70:…
- Name Identifier Format: urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
The IdP at a minimum needs to know where to send the assertions.
- Assertion Consumer Service URL: http://www.hostedservice.com/sso/saml/acs
SAML uses public/private key combination to sign and verify requests and their response. If a fingerprint is not provided you can generate it from the x.509 certificate.
openssl x509 -noout -in cert.pem -fingerprint
Now that you understand the transaction and configuration, try adding SAML support to your Rails/Sinatra application. I chose the ruby-saml gem created by OneLogin to handle the technical details. The README has all the instructions you need to get started. ProTip: A helpful development tool for watching the request/response exchange is the SSO-Tracer plugin for Firefox.
The two routes you need are for initiating login (AuthnRequest) with the IdP (Ex./sso/saml/login) and for consuming the assertion messages (Ex. /sso/saml/acs).
User Provisioning with SAML
Not only can we authenticate existing users but we can auto-provision accounts for first-time logins. This is a great way to reduce account administration between systems. The SAML Response to the Service Provider can contain a list of user attributes (email, username, first/last name, etc) that can be used to provision a new account. In your assertion consumer method (/sso/saml/acs), if you find that the user does not exist in your system you can redirect to a new user workflow or auto-provision based on the provided attributes.
Over the last couple months I’ve thought many times: “How can I get public/external access to my local machine?” I’ve been working with OAuth providers that want a callback URL and integrating a Rails application with Salesforce. I wanted those public applications to talk to my local machine for ease of development. Sure I could push my project to Heroku or some other public server but it’s just so much easier to have things local for quick development and debugging.
These instructions assume you are connected to a router (probably wireless), that you can administer, which is connected to your ISP’s cable modem.
1) Enable the DMZ function of your router. I’m using DD-WRT which gives me some additional functionality so hopefully you can find a DMZ option in your configuration. NOTICE: “Enabling this option will expose the specified host to the Internet. All ports will be accessible from the Internet.” It’s recommended to have a firewall enabled on your machine to protect yourself.
The configuration should ask for a specific IP to route all public traffic to. Find the IP address assigned to you (typically in the 192.168.x.x range) and punch it in.
2) Now that you’re machine is accessible you need to know the external IP to use. The easiest way is to find the WAN IP listed in the admin console of your router. If your router allows shell access you can also ssh in and run ifconfig or some variant to get the external IP.
You should now be able to visit that external IP from your browser and it will resolve to port 80 on your local machine. Yay!
If you don’t have anything running on port 80 you’ll likely get an error response. If you’re running a rails server, use pu.bl.ic.ip:3000.
3) Taking it a step further is routing an official domain name to the public IP we found in step 2. I purchased a domain for personal use and then created a new DNS A Record that points a specific subdomain (localhost.mydomain.com) to the public IP of my cable modem.
Now I can just type in a domain name and I’m routed directly to my laptop.
Yes, my locally assigned IP could change and I’d need to update the router DMZ configuration.
Yes, it’s possible that my cable modem IP will change and I’d need to update the DNS A Name record.
I started working on a new rails project and wanted to use specific domain names and route traffic through port 80. There are several ways to setup Apache as front to your Rails application but I only wanted stock Apache and a standalone rails instance. I didn’t want to hassle with anything else.
1) Start your Rails server as you normally would. Let’s assume it’s running at http://localhost:3000
2) Create an Apache Virtual Host that proxies requests to http://localhost:3000
3) Edit your /etc/hosts file to route test.application.vhost to 127.0.0.1
Notes for Mac OS Lion
Virtual Hosts are configured in /etc/apache2/extra/httpd-vhosts.conf
If necessary, modify “/etc/apache2/httpd.conf” and uncomment the line “Include /private/etc/apache2/extra/httpd-vhosts.conf”
sudo apachectl configtest
sudo apachectl restart
- Got sucked into Downton Abbey. Watched Season 1 using Amazon Video On Demand. Thanks to the 30 day Amazon Prime trial.
- Learned about the engineyard gem for command line deployments (ey deploy).
- Introduced to Librarian-Chef and the Cheffile for managing infrastructure repositories (
gem install librarian).
- Static analyzer tool for numerous languages – Code Surveyor
- Learned that Google is offering all these services from their Cloud Platform
- Linter for Opscode Chef cookbooks: foodcritic
- Learning how to make sourdough bread from a starter.
- Learned how to do a many-to-many relationship in Rails using both has_many => :through and has_and_belongs_to_many
- The screenshot.png file in your WordPress theme is displayed when selecting a theme.
- Learned that oci_fetch_all doesn’t respect the OCI_BOTH flag but oci_fetch_array does. Boo.
- How to deploy to Heroku via TravisCI
- Learned the formula for converting between Celsius and Farhrenheit: (C * 9/5) + 32 = F and the opposite is (F – 32) * 5/9 = C
- Learned about http://pygments.appspot.com/ while learning about Resque for Rails.
- The YUM package manager stands for “Yellowdog Updater, Modified”. A rewrite of Yellowdog Updater (YUP).
- Learned about the sudoku-like kenken
- Used GitHub OAuth Plugin to setup authentication on a local Jenkins instance.
- Implemented DbalSessionStorage object for Symfony 2.0, based on the 2.2 version
- Learned how to make homemade flour tortillas.
- Learned about
__PHP_Incomplete_Classand that I needed to autoload a class to avoid it.
- Signed up for NewRelic.com and got a free Nerd Life t-shirt.
- Got a history lesson about Hanakkah, never knew much about it.
- Experienced Raclette for the first time.
- Made croissant dough from scratch on my way to making egg souffles.
- Learned that a movie runtime includes the closing credits.
- How to setup custom domains with Heroku.
- Learned why NORAD started tracking Santa.
- LEGO – Comes from Danish words LEG GODT (play well). LEGO in Latin means “I put together”
- YARD – Ruby Documentation
- NatGeo LEGO is impressive.
- 12 Days of Christmas has more meaning than I realized. The 12 days are between Dec 25 and Jan 6.
- Learned about Ruby’s & operator to switch between a Proc to block and block to Proc.
- Learned how to create a custom UIViewTableCell and respond to different static table rows.
- Rails Authorization with CanCan
- iPhone SDK: NSUserDefaults
- Learned about mod_rpaf and passing client ips to apache from nginx.
- Learned about rails_upgrade plugin for converting app from Rails 2 to Rails 3
- Attended my first Virginia Tech football game (VT vs FSU)
- Ate at Biscuitville for the first time
- Indonesia consists of ~17,500 islands and ~742 different languages and dialects.
- Learning about Rails after_find and after_initialize callbacks and their usage difference with Rails 2 and 3.
- Used UISwitch and NSUserDefaults in an iPhone application to create a Favorites table view.
- Learned how to use savon to talk to the MindBody API
- Learned how to use UIView tag property to store an integer value and pass it along to the next view controller when performing a segue.
- Learned about http://platform.fatsecret.com/ and the fatsecret Ruby gem for talking to their RESTful API.
- Used devise gem in a rails application for the first time.
- Made my first real pumpkin pie from scratch. Included roasting the pumpking and making the crust by hand.
- Cryptic Ruby Global Variables and Their Meanings
- Learned about gettinderbox.com for proposal and contract management.
- Learned that letting dough rise all day causes the yeast and sugar to ferment and make perfectly good cinnamon rolls taste bad.
- Signed up for Amazon CloudDrive (5G free and dirt cheap for larger plans)
- Discovered ‘Send to Kindle‘ Chrome plugin.
- Shot a SigSauer P229 9MM, GLOCK .45 and S&W 38 Special revolver for the first time.
- Learned about some really cool work being done at http://www.invincea.com/ for threat prevention and detection.
- Learned that Jenkin’s LDAP managerPassword is stored base64 encoded.
- Learned about http://www.browserstack.com/ for cloud based browser testing.
- Learned about rack-offline and html manifest file to support offline browsing.
- KnpLabs/snappy and mreiferson/php-wkhtmltox based on wkhtmltopdf
- Learned how to associate a filetype for VIM syntax highlighting.
- Learning how to write a PHP extension in C.
- Visited local motorcycle dealer and learned about rear, mid and forward controls. Since I’m tall, forward is preferred.
- Motorcycle Lingo: Hardtail has no rear suspension, Softtail does.
- Learned how to work with PHP ZVALs and resources when writing an extension in C.
- SQLPlus: NEW_VALUE
- git archive ––format=zip
- Learned of Oracle’s DBMS_SQL package.
- Learned “basima” means thank you (to a man) in Assyrian. Their language has specific words when directed towards men or women.
- Learned Little Nemo by Winsor McCay was a comic strip before it was an NES game. Thanks Google.
- Learned more about Symfony2 custom authentication providers.
- Learned what a Tail call is.
- Switch between Mac Terminal windows using CMD+1, CMD+2, CMD+N
- HTTP Status Code 418
- Learned from a friend how iPhone Application submission and acceptance/rejection works.
- Twitter’s recess project
- Learned about XCode’s Storyboard functionality (iPhone).
- Learned how to use NSURLConnection to fetch JSON data and then parse and display it on the screen.
- Learned how to use the MapView object and plot locations on a map (iPhone).
- Used Google’s Geocoding API to turn an address into a Coordinate.
- Watched first Stanford University iPhone Development course on iTunes. Learning Objective-C syntax.
- Learned how to use NSNotificationCenter to notify controllers when data is available (iPhone).
- Learned how to post JSON data to a Rails create endpoint from an iPhone application.
- Learned and used Ruby Geocoder via Railscast.
- Learned how to pass data between view controllers with segue (iPhone).
- http://smarterer.com (Skills Tests) and http://typing.io (Typing Test for Programmers)
- GitHub’s http://get.gaug.es/