2011-05-10 37 views

回答

5

我覺得在我們的文檔文章給人的感覺的Zendesk SSO時很難實際上它非常簡單(http://www.zendesk.com/api/remote-authentication)。

# reference http://www.zendesk.com/api/remote-authentication 
# you need to be a Zendesk account admin to enable remote auth (if you have not already) 
# go to Settings > Security, click "Enabled" next to Single Sign-On 

# three important things to pay attention to: 
# Remote Login URL, Remote Logout URL, and shared secret token 

# for testing on a Rails 3 application running on localhost, fill in the Remote Login URL to map 
# to http://localhost:3000/zendesk/login (we will need to make sure routes for that exist) 

# fill in Remote Logout URL to http://localhost:3000/zendesk/logout 

# copy the secret token, you'll need it later 


# first, let's create those routes in config/routes.rb 
namespace :zendesk do 
    match "/login" => "zendesk#login" # will match /zendesk/login 
    match "/logout" => "zendesk#logout" # will match /zendesk/logout 
end 

# Above I've mapped those requests to a controller named "zendesk" but it can be named anything 

# next we want to add our secret token to the application, I added this in an initializer 
# config/initializers/zendesk_auth.rb 
ZENDESK_REMOTE_AUTH_TOKEN = "< your token >" 
ZENDESK_REMOTE_AUTH_URL = "http://yourcompany.zendesk.com/access/remote/" 

# Assuming we have a controller called zendesk, in zendesk_controller.rb 

require "digest/md5" 
class ZendeskController < ApplicationController 

    def index 
    @zendesk_remote_auth_url = ZENDESK_REMOTE_AUTH_URL 
    end 

    def login 
    timestamp = params[:timestamp] || Time.now.utc.to_i 
    # hard coded for example purposes 
    # really you would want to do something like current_user.name and current_user.email 
    # and you'd probably want this in a helper to hide all this implementation from the controller 
    string = "First Last" + "[email protected]" + ZENDESK_REMOTE_AUTH_TOKEN + timestamp.to_s 
    hash = Digest::MD5.hexdigest(string) 
    @zendesk_remote_auth_url = "http://yourcompany.zendesk.com/access/remote/?name=First%20Last&[email protected]&timestamp=#{timestamp}&hash=#{hash}" 
    redirect_to @zendesk_remote_auth_url 
    end 

    def logout 
    flash[:notice] = params[:message] 
    end 
end 

# Note that the above index action defines an instance variable @zendesk_remote_auth_url 
# in my example I simple put a link on the corresponding view that hits ZENDESK_REMOTE_AUTH_URL, doing so 
# will cause Zendesk to hit your applications Remote Login URL (you defined in your Zendesk SSO settings) and pass a timestamp back in the URL parameters 
# BUT, it is entirely possible to avoid this extra step if you just want to go to /zendesk/login in your app 
# notice I am either using a params[:timestamp] if one exists or creating a new timestamp with Time.now 

這個例子很簡單,但我只想說明Zendesk SSO的基本機制。請注意,我沒有觸及創建新用戶或編輯現有用戶這一更復雜的問題,只需登錄擁有現有Zendesk帳戶的用戶即可。

+0

'的Zendesk :: RemoteAuth.auth_url =「https://開頭civicrush.zendesk.com /訪問/ remoteauth'' '的Zendesk :: RemoteAuth.token ='blah8blah'' – chaserx 2012-08-29 00:39:09

+0

此外,Zendesk現在需要使用管道分隔URL中包含的參數。 http://www.zendesk.com/support/api/remote-authentication 'input = name +「|」 +電子郵件+「|」 + external_id +「|」 +組織+「|」 +標籤+「|」 + remote_photo_url +「|」 +令牌+「|」 +時間戳 散列= md5(輸入)' – chaserx 2012-08-29 00:53:32

+1

已更新:Zendesk棄用遠程認證系統以支持基於JSON Web令牌的新方法:https://support.zendesk.com/entries/23675367-Setting-up-單點登錄與 - 智威湯遜 - JSON的Web-令牌的 – 2013-05-07 19:54:07

5

有從的Zendesk更新的示例代碼

# Using JWT from Ruby is straight forward. The below example expects you to have `jwt` 
# in your Gemfile, you can read more about that gem at https://github.com/progrium/ruby-jwt. 
# Assuming that you've set your shared secret and Zendesk subdomain in the environment, you 
# can use Zendesk SSO from your controller like this example. 

class ZendeskSessionController < ApplicationController 
    # Configuration 
    ZENDESK_SHARED_SECRET = ENV["ZENDESK_SHARED_SECRET"] 
    ZENDESK_SUBDOMAIN  = ENV["ZENDESK_SUBDOMAIN"] 

    def create 
    if user = User.authenticate(params[:login], params[:password]) 
     # If the submitted credentials pass, then log user into Zendesk 
     sign_into_zendesk(user) 
    else 
     render :new, :notice => "Invalid credentials" 
    end 
    end 

    private 

    def sign_into_zendesk(user) 
    # This is the meat of the business, set up the parameters you wish 
    # to forward to Zendesk. All parameters are documented in this page. 
    iat = Time.now.to_i 
    jti = "#{iat}/#{rand(36**64).to_s(36)}" 

    payload = JWT.encode({ 
     :iat => iat, # Seconds since epoch, determine when this token is stale 
     :jti => jti, # Unique token id, helps prevent replay attacks 
     :name => user.name, 
     :email => user.email, 
    }, ZENDESK_SHARED_SECRET) 

    redirect_to zendesk_sso_url(payload) 
    end 

    def zendesk_sso_url(payload) 
    "https://#{ZENDESK_SUBDOMAIN}.zendesk.com/access/jwt?jwt=#{payload}" 
    end 
end