diff --git a/app/controllers/account_controller.rb b/app/controllers/account_controller.rb
index b0a5b42..2716340 100644
--- a/app/controllers/account_controller.rb
+++ b/app/controllers/account_controller.rb
@@ -19,12 +19,17 @@ class AccountController < ApplicationController
   helper :custom_fields
   include CustomFieldsHelper   
   
+  @cas_initialized = false
+  class << self; attr_accessor :cas_initialized; end
+
   # prevents login action to be filtered by check_if_login_required application scope filter
   skip_before_filter :check_if_login_required
 
   # Login request and validation
   def login
-    if request.get?
+    if Setting.cas? && Setting.cas_force != '0' && !session[:cas_user]
+      cas_authenticate
+    elsif request.get?
       logout_user
     else
       authenticate_user
@@ -34,7 +39,7 @@ class AccountController < ApplicationController
   # Log out current user and redirect to welcome page
   def logout
     logout_user
-    redirect_to home_url
+    redirect_to home_url unless Setting.cas?
   end
   
   # Enable user to choose a new password
@@ -125,12 +130,64 @@ class AccountController < ApplicationController
     redirect_to :action => 'login'
   end
   
+  def cas_authenticate
+    unless self.class.cas_initialized
+      CASClient::Frameworks::Rails::Filter.configure(
+        :cas_base_url => Setting.cas_base_url
+      )
+      self.class.cas_initialized = true
+    end
+
+    CASClient::Frameworks::Rails::Filter.filter(self) unless session[:cas_user]
+    if session[:cas_user]
+      user = User.find_or_initialize_by_login(session[:cas_user])
+      if user.new_record?
+        # Self-registration off
+        redirect_to(home_url) && return unless Setting.self_registration?
+
+        # Create on the fly
+        user.login = session[:cas_user]
+        user.mail = session[:cas_user] + Setting.cas_email_suffix
+        user.firstname = session[:cas_user]
+        user.lastname = session[:cas_user]
+        user.random_password
+        user.status = User::STATUS_REGISTERED
+
+        case Setting.self_registration
+        when '1'
+          register_by_email_activation(user) do
+            onthefly_creation_failed(user)
+          end
+        when '3'
+          register_automatically(user) do
+            onthefly_creation_failed(user)
+          end
+        else
+          register_manually_by_administrator(user) do
+            onthefly_creation_failed(user)
+          end
+        end
+      else
+        # Existing record
+        if user.active?
+          successful_authentication(user)
+        else
+          account_pending
+        end
+      end
+    end
+  end
+
   private
   
   def logout_user
     if User.current.logged?
       cookies.delete :autologin
       Token.delete_all(["user_id = ? AND action = ?", User.current.id, 'autologin'])
+
+      # Log out of CAS if its there
+      CASClient::Frameworks::Rails::Filter.logout(self, home_url) if Setting.cas?
+
       self.logged_user = nil
     end
   end
@@ -197,7 +254,7 @@ class AccountController < ApplicationController
       end
     end
   end
-  
+
   def successful_authentication(user)
     # Valid user
     self.logged_user = user
diff --git a/app/models/setting.rb b/app/models/setting.rb
index 70d8f2b..7b46438 100644
--- a/app/models/setting.rb
+++ b/app/models/setting.rb
@@ -143,6 +143,10 @@ class Setting < ActiveRecord::Base
   def self.openid?
     Object.const_defined?(:OpenID) && self[:openid].to_i > 0
   end
+
+  def self.cas?
+    Object.const_defined?(:CAS) && self[:cas].to_i > 0
+  end
   
   # Checks if settings have changed since the values were read
   # and clears the cache hash if it's the case
diff --git a/app/views/account/login.rhtml b/app/views/account/login.rhtml
index fad59e9..1b3e7a9 100644
--- a/app/views/account/login.rhtml
+++ b/app/views/account/login.rhtml
@@ -26,6 +26,13 @@
     </td>
 </tr>
 <tr>
+  <% if Setting.cas? %>
+    <tr>
+        <td align="left">
+            <%= link_to l(:label_cas_login), :controller => 'account', :action => 'cas_authenticate' %>
+        </td>
+    </tr>
+  <% end %>
     <td align="left">
         <% if Setting.lost_password? %>
             <%= link_to l(:label_password_lost), :controller => 'account', :action => 'lost_password' %>
diff --git a/app/views/settings/_authentication.rhtml b/app/views/settings/_authentication.rhtml
index 81814bb..196ad19 100644
--- a/app/views/settings/_authentication.rhtml
+++ b/app/views/settings/_authentication.rhtml
@@ -16,6 +16,14 @@
 
 <p><%= setting_check_box :openid, :disabled => !Object.const_defined?(:OpenID) %></p>
 
+<p><%= setting_check_box :cas, :disabled => !Object.const_defined?(:CAS) %></p>
+
+<p><%= setting_text_field :cas_base_url, :disabled => !Object.const_defined?(:CAS), :size => 50 %></p>
+
+<p><%= setting_text_field :cas_email_suffix, :disabled => !Object.const_defined?(:CAS), :size => 50 %></p>
+
+<p><%= setting_check_box :cas_force, :disabled => !Object.const_defined?(:CAS) %></p>
+
 <p><%= setting_check_box :rest_api_enabled %></p>
 </div>
 
diff --git a/config/environment.rb b/config/environment.rb
index f89695f..8af6630 100644
--- a/config/environment.rb
+++ b/config/environment.rb
@@ -57,4 +57,5 @@ Rails::Initializer.run do |config|
   if File.exists?(File.join(File.dirname(__FILE__), 'additional_environment.rb'))
     instance_eval File.read(File.join(File.dirname(__FILE__), 'additional_environment.rb'))
   end
+  config.action_controller.session = { :key => "_myapp_session", :secret => "ksadjfklasdjfkl;asdjfkljasd;klfjasdkl;fj;klasdjfkl;jsdl;kfajsdkfj;aklsdjfk;j" }
 end
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 351de3b..3c6b3ee 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -327,6 +327,10 @@ en:
   setting_file_max_size_displayed: Max size of text files displayed inline
   setting_repository_log_display_limit: Maximum number of revisions displayed on file log
   setting_openid: Allow OpenID login and registration
+  setting_cas: Use CAS login and registration
+  setting_cas_base_url: CAS server base URL
+  setting_cas_email_suffix: Default email suffix for CAS users
+  setting_cas_force: ONLY allow login using CAS (this disables normal login)
   setting_password_min_length: Minimum password length
   setting_new_project_user_role_id: Role given to a non-admin user who creates a project
   setting_default_projects_modules: Default enabled modules for new projects
@@ -454,6 +458,7 @@ en:
   label_register: Register
   label_login_with_open_id_option: or login with OpenID
   label_password_lost: Lost password
+  label_cas_login: Login using CAS
   label_home: Home
   label_my_page: My page
   label_my_account: My account
diff --git a/config/settings.yml b/config/settings.yml
index 1e905ed..172a2f3 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -182,3 +182,11 @@ start_of_week:
   default: ''
 rest_api_enabled:
   default: 0
+cas:
+  default: 0
+cas_base_url:
+  default: ''
+cas_email_suffix:
+  default: ''
+cas_force:
+  default: 0
