跨域认证ASP.net MVC

Cross-domain authentication ASP.net MVC

我有两个使用 ASP.net MVC 构建的不同 Web 应用程序。这两个应用程序可能 运行 不在同一服务器或同一域中。

我希望如果用户登录其中一个,则应该自动登录另一个。同样适用于注销。

您认为哪个是最佳解决方案?您知道一些示例代码吗?

谢谢!

--- 编辑了更多信息 ---

用例场景:

用户在选项卡上打开了 web 应用程序 A,并且在应用程序的某个位置有一个 link 将用户重定向到 网络应用程序 B。如果他在 A 上登录,我想向他显示整个页面,如果他没有登录,则将他重定向到登录表单。

为什么我需要这样做:

应用程序 AB 已经构建。显然,访问 B 的唯一方法是单击 A 中的 link,只有您之前登录过才会显示.问题是,如果您知道 B 的某个页面的 URL (又长又复杂,但仍然如此),您可以将其写在浏览器上并访问 B,表示安全问题

我想你追求的是CAS(Central Authentication Service) https://en.wikipedia.org/wiki/Central_Authentication_Service

有许多可用的 CAS 提供程序。我建议你看看这个 https://wiki.jasig.org/display/CAS/Home

it will give you number of out-of-the-box solutions exist to enable web services written in a specific language, or based on a framework, to use CAS. This will help you implement a SSO solution in a matter of hours

我的答案可能不是最好的,但是你可以使用一些棘手的机制,比如

  1. 无论何时您要进行另一个应用程序,您都需要将一个令牌从应用程序 A 传递到 B。
  2. 在 B 站点验证此令牌。
  3. 并根据令牌授权该用户。 (我的意思是应用静默或后门登录)

感谢 @Kaushik Thanki 的回答,我已经实现了一些代码来解决我的问题。我将 post 此处提供适合我的解决方案,即使它不是最佳选择。

首先,我在 A 中实现了一种向 B 发出 Post 请求的方法。在这个方法中,我获取了用户的 ID,并使用一些其他参数和密码对其进行了 hash。然后,我向 B 发送用户 ID、哈希值和一个用于在登录和注销之间进行选择的布尔值。

private void SendPostRequest(bool login)
        {
            // Create the combine string
            string data = // userId combined with more stuff

            // Create the hash of the combine string
            HashAlgorithm algorithm = MD5.Create();
            byte[] hash = algorithm.ComputeHash(Encoding.UTF8.GetBytes(data));
            StringBuilder sb = new StringBuilder();
            foreach (byte b in hash)
                sb.Append(b.ToString("X2"));

            string encriptedData = sb.ToString();

            // Fill the url with the path and the data
            string url = "http://localhost/xxx/yyy/ExternalAuthentication/Login?id=" + _cachedCustomer.Id + "&hash=" + encriptedData + "&login=" + login.ToString();

            // Make the Post request
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream resStream = response.GetResponseStream();
        }

之后,我在 B 中创建了一个新的 class 来处理登录逻辑。我使用 HttpContext.Current.Application 变量来存储身份验证的状态:

public class ExternalAuthenticationController : Controller
        {

            public ActionResult Index()
            {
                return View();
            }

            public ActionResult Login(string id, string hash, string login)
            {
               // Create the combine string
               string data = //user id + same stuff than in A;

               // Create the hash of the combine string
               HashAlgorithm algorithm = MD5.Create();
               byte[] hashArray =    algorithm.ComputeHash(Encoding.UTF8.GetBytes(data));
               StringBuilder sb = new StringBuilder();
               foreach (byte b in hashArray)
                  sb.Append(b.ToString("X2"));
               string originalHash = sb.ToString();

               // Compare the two hash. If they are the same, create the variable
               if (hash.CompareTo(originalHash) == 0)
               {

               if (System.Web.HttpContext.Current.Application["Auth"] == null)
               {
                   System.Web.HttpContext.Current.Application["Auth"] = false;
               }

               if (Convert.ToBoolean(login))
               {
                   System.Web.HttpContext.Current.Application["Auth"] = true;
               }

              else
              {
                  System.Web.HttpContext.Current.Application["Auth"] = false;
              }
             }
         }

可能@vijay shiyani提供的答案更好更笼统,但从我的角度来看,它需要很多时间来实现。

您可以在一个项目中实现OAuth。您可以在这里获得更多帮助:http://www.openauthentication.org/about

OWIN OAuth 2.0 授权服务器 http://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server

我假设您无法使用任何共享存储在应用程序 A 和 B 之间进行通信。 (这可能允许一些共享会话实现)。

更符合行业标准的方式 (OpenID Connect) 就像其他一些答案所暗示的那样。我会尝试提供更多详细信息,让您走上正轨。

应用程序 A 和 B 都应将身份验证过程中继给受信任的第三方(可以托管在 A、B 或完全不同的应用程序中)- 我们称之为 C

当用户到达 A 或 B(无论 B 有奇怪的复杂 URL,她总是可以将它们添加为书签)时,他的请求应该包含一个授权令牌。如果没有,她就没有通过身份验证,将被重定向到 C 并提供一些登录机制 - 比如 user/pass 表单。

成功登录后,她将被重定向回 A/B(取决于她来自哪里)以完成她使用身份验证令牌所做的一切。现在,有了身份验证令牌,她就通过了身份验证。

如果她通过 A 的身份验证然后重定向到 B,则此重定向也应包含令牌,B 将知道如何信任该令牌。

现在,如果他只是打开一个新标签页,B 将看不到任何令牌,因此她将被重定向到 C,然后又被重定向回(她已经通过身份验证,还记得吗?)令牌,现在一切都很好。

我描述的是使用 OpenID 连接的常见流程,如果使用 .net,我真的建议使用 Thinktecture 的 IdentityServer 来为您完成艰苦的工作并成为您的 "C"。

另一种选择是为此类 "C" 托管为 SaaS 应用程序付费 - 查看 Auth0