diff --git a/src/CasLogic.js b/src/CasLogic.js
new file mode 100644
index 0000000000000000000000000000000000000000..1bcc6d5c78e4e026844e25a225038aa5ac7986ba
--- /dev/null
+++ b/src/CasLogic.js
@@ -0,0 +1,28 @@
+/*
+Copyright 2015 OpenMarket Ltd
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+'use strict';
+
+var url = require ('url');
+
+function getServiceUrl() {
+    var parsedUrl = url.parse(window.location.href);
+    return parsedUrl.protocol + "//" + parsedUrl.host + parsedUrl.pathname;
+}
+
+module.exports = {
+    getServiceUrl: getServiceUrl
+};
diff --git a/src/controllers/organisms/CasLogin.js b/src/controllers/organisms/CasLogin.js
new file mode 100644
index 0000000000000000000000000000000000000000..9c58d32c06fca87894db815b6df852f32414572f
--- /dev/null
+++ b/src/controllers/organisms/CasLogin.js
@@ -0,0 +1,37 @@
+/*
+Copyright 2015 OpenMarket Ltd
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+'use strict';
+
+var React = require("react");
+var MatrixClientPeg = require("../../MatrixClientPeg");
+var Cas = require("../../CasLogic");
+
+module.exports = {
+
+    onCasClicked: function(ev) {
+        var serviceRedirectUrl = Cas.getServiceUrl() + "#/login/cas";
+        var self = this;
+        MatrixClientPeg.get().getCasServer().done(function(data) {
+            var serverUrl = data.serverUrl + "/login?service=" + encodeURIComponent(serviceRedirectUrl);
+            window.location.href = serverUrl;
+        }, function(error) {
+            self.setStep("stage_m.login.cas");
+            self.setState({errorText: 'Login failed.'});
+        });
+    },
+
+};
diff --git a/src/controllers/pages/MatrixChat.js b/src/controllers/pages/MatrixChat.js
index 2120b2fd10d04afd27a49e370fb12db67375b68c..2a560797089537d0b22195760236bc72b0e880e3 100644
--- a/src/controllers/pages/MatrixChat.js
+++ b/src/controllers/pages/MatrixChat.js
@@ -23,6 +23,8 @@ var q = require("q");
 var sdk = require('../../index');
 var MatrixTools = require('../../MatrixTools');
 
+var Cas = require("../../CasLogic");
+
 module.exports = {
     PageTypes: {
         RoomView: "room_view",
@@ -128,6 +130,30 @@ module.exports = {
                     screen: 'login'
                 });
                 this.notifyNewScreen('login');
+                break;
+            case 'cas_login':
+                if (this.state.logged_in) return;
+
+                var self = this;
+                var client = MatrixClientPeg.get();
+                var serviceUrl = Cas.getServiceUrl();
+
+                client.loginWithCas(payload.params.ticket, serviceUrl).done(function(data) {
+                    MatrixClientPeg.replaceUsingAccessToken(
+                        client.getHomeserverUrl(), client.getIdentityServerUrl(),
+                        data.user_id, data.access_token
+                    );
+                    self.setState({
+                        screen: undefined,
+                        logged_in: true
+                    });
+                    self.startMatrixClient();
+                    self.notifyNewScreen('');
+                }, function(error) {
+                    self.notifyNewScreen('login');
+                    self.setState({errorText: 'Login failed.'});
+                });
+
                 break;
             case 'view_room':
                 this.focusComposer = true;
@@ -336,6 +362,11 @@ module.exports = {
                 action: 'start_login',
                 params: params
             });
+        } else if (screen == 'cas_login') {
+            dis.dispatch({
+                action: 'cas_login',
+                params: params
+            });
         } else if (screen.indexOf('room/') == 0) {
             var roomString = screen.split('/')[1];
             if (roomString[0] == '#') {