2015-09-22 42 views
1

使用Meteorcoffeescriptiron-router,我成功地获得来自SAML身份提供程序(IDP)的用户。如何登录服务器端获取的SSO用户到Meteor帐户包中?

如何使用这些用户信息来登录,在通过流星账户包的用户?

考虑以下的服务器端路线:

Router.route '/sso/saml2', where: 'server', name:'ssoSaml' 
    .get -> 
     @response.writeHead 302, 'Location': saml.getRequestUrl() 
     @response.end() 
    .post -> 
     {secret:{password, email}, profile, state} = saml.getProfile @request.body.SAMLResponse 
     user= Meteor.users.findOne {'profile.domainId': profile.domainId} 
     userId = if user? then user._id else Accounts.createUser {password, email, profile} 
     # I have the user id - How do I sign the user in? 
     @response.writeHead 302, 'Location': "#{state.location}" 
     @response.end() 

的过程如下:

  • 的GET路线将浏览器重定向到的IdP终点与适当生成SAMLRequest
  • 对IDP处理SAMLRequest,并返回一个SAMLResponse到POST路径。
  • SAMLResponse处理返回用户的secret领域,公共profile以及包含最初请求location
  • 一个state对象的唯一,不变的profile.domainId用于从流星user收集检索用户
  • 如果没有user存在一个新的创建。

在这个过程的最后我有用户的详细信息,我知道用户存在于Meteor.users集合中。要完成我需要登录用户并重定向到最初请求的位置。

如何登入用户?

回答

2

最终,登录调用,设置用户必须从客户端代码进行。

  1. 定义集合登录令牌:

    @LoginTokens = new Mongo.Collection 'loginTokens' 
    
  2. 使用原来的服务器端的路线,但创建一个一次性登录令牌客户端使用登录,然后重定向到客户端路由,传递令牌。

    Router.route '/sso/saml2', where: 'server', name:'ssoSaml' 
        .get -> 
         @response.writeHead 302, 'Location': saml.getRequestUrl() 
         @response.end() 
        .post -> 
         {secret:{password, email}, profile, state} = saml.getProfile @request.body.SAMLResponse 
         user= Meteor.users.findOne {'profile.domainId': profile.domainId} 
         userId = if user? then user?._id else Accounts.createUser {password, email, profile} 
         tokenId = LoginTokens.insert { userId, expires: +(new Date)+tokenExpirationInMilliseconds } 
         @response.writeHead 302, 'Location': "/sso/login/#{tokenId}?loc=#{state.location}" 
         @response.end() 
    
  3. 注册服务器上的自定义登录处理程序接受和验证登录令牌:

    Accounts.registerLoginHandler ({tokenId})-> 
        {userId} = LoginTokens.findOne tokenId or {} 
        return {userId} if userId? 
    
  4. 调用此处理程序在接收登录令牌您的客户端路由客户端上,但确保参数的这种奇怪的签名(注意数组)匹配:

    Router.route '/sso/login/:tokenId', -> 
        {tokenId, query} = @params 
        Accounts.callLoginMethod 
         methodArguments: [{tokenId}] 
         userCallback: -> 
          Router.go if query?.loc? then query.loc else '/' 
    
  5. 最后,在服务器上创建一个作业定期清除过期的令牌:

    Meteor.setInterval -> 
        LoginTokens.remove { expires: { $lte: +(new Date) } } 
    , 1000 
    

**注:一定要传递包含登录令牌作为methodArguments数组中的元素调用的登录方法时,另外一个对象,在登录处理程序,请返回一个对象userId属性,该属性的值是用户的用户标识,以匹配预期签名。

+0

您提到POST路由应该在客户端上运行。你能告诉我如何在这里SAMLResponse数据?在服务器上你可以看到我通过'@ request.body.SAMLResponse'得到它,但我找不到客户端路由的等价物。谢谢。 – biofractal

+0

请参阅上面的**编辑1 **获取更多详细信息。 – biofractal

+0

我相信已取得进展 - 感谢您的努力。请参阅**编辑2 **获取最新版本。 – biofractal

相关问题