NewLife/X

OAuth支持跳转到到验证中心注销,并指定返回地址
大石头 编写于 2018-04-03 11:24:33
共计: 修改3个文件,增加65行、删除16行。
修改 +2 -1
修改 +33 -1
修改 +30 -14
修改 +2 -1
diff --git a/NewLife.Core/Web/OAuth/TaobaoClient.cs b/NewLife.Core/Web/OAuth/TaobaoClient.cs
index 136b526..6765ac7 100644
--- a/NewLife.Core/Web/OAuth/TaobaoClient.cs
+++ b/NewLife.Core/Web/OAuth/TaobaoClient.cs
@@ -3,7 +3,7 @@ using System.Collections.Generic;
 
 namespace NewLife.Web.OAuth
 {
-    /// <summary>身份验证提供者</summary>
+    /// <summary>淘宝身份验证提供者</summary>
     public class TaobaoClient : OAuthClient
     {
         /// <summary>实例化</summary>
@@ -14,6 +14,7 @@ namespace NewLife.Web.OAuth
             AuthUrl = url + "authorize?response_type={response_type}&client_id={key}&redirect_uri={redirect}&state={state}&scope={scope}";
             AccessUrl = url + "token?grant_type=authorization_code&client_id={key}&client_secret={secret}&code={code}&state={state}&redirect_uri={redirect}";
             //UserUrl = "https://openapi.baidu.com/rest/2.0/passport/users/getLoggedInUser?access_token={token}";
+            LogoutUrl = url + "logoff?client_id={key}&view=web";
         }
 
         /// <summary>从响应数据中获取信息</summary>
修改 +33 -1
diff --git a/NewLife.Core/Web/OAuthClient.cs b/NewLife.Core/Web/OAuthClient.cs
index b2538b5..08d21b4 100644
--- a/NewLife.Core/Web/OAuthClient.cs
+++ b/NewLife.Core/Web/OAuthClient.cs
@@ -215,7 +215,11 @@ namespace NewLife.Web
                 if (UserUrl.IsNullOrEmpty() && dic.ContainsKey("scope"))
                 {
                     var ss = dic["scope"].Trim().Split(",");
-                    if (ss.Contains("UserInfo")) UserUrl = "userinfo?access_token={token}";
+                    if (ss.Contains("UserInfo"))
+                    {
+                        UserUrl = "userinfo?access_token={token}";
+                        LogoutUrl = "logout?client_id={key}&redirect_uri={redirect}&state={state}";
+                    }
                 }
 
                 OnGetInfo(dic);
@@ -324,6 +328,34 @@ namespace NewLife.Web
         }
         #endregion
 
+        #region 5-注销
+        /// <summary>注销地址</summary>
+        public String LogoutUrl { get; set; }
+
+        /// <summary>注销</summary>
+        /// <param name="redirect">完成后调整的目标地址</param>
+        /// <param name="state">用户状态数据</param>
+        /// <param name="baseUri">相对地址的基地址</param>
+        /// <returns></returns>
+        public virtual String Logout(String redirect = null, String state = null, Uri baseUri = null)
+        {
+            var url = LogoutUrl;
+            if (url.IsNullOrEmpty()) throw new ArgumentNullException(nameof(LogoutUrl), "未设置注销地址");
+
+#if !__CORE__
+            // 如果是相对路径,自动加上前缀。需要考虑反向代理的可能,不能直接使用Request.Url
+            redirect = redirect.AsUri(baseUri) + "";
+#endif
+            _redirect = redirect;
+            _state = state;
+
+            url = GetUrl(url);
+            WriteLog("Logout {0}", url);
+
+            return url;
+        }
+        #endregion
+
         #region 辅助
         /// <summary>替换地址模版参数</summary>
         /// <param name="url"></param>
修改 +30 -14
diff --git a/NewLife.Cube/Controllers/SsoController.cs b/NewLife.Cube/Controllers/SsoController.cs
index 81ba8b3..cd9afdf 100644
--- a/NewLife.Cube/Controllers/SsoController.cs
+++ b/NewLife.Cube/Controllers/SsoController.cs
@@ -1,13 +1,11 @@
 using System;
 using System.IO;
 using System.Linq;
-using System.Threading.Tasks;
 using System.Web.Mvc;
 using NewLife.Cube.Entity;
 using NewLife.Cube.Web;
 using NewLife.Log;
 using NewLife.Model;
-using NewLife.Reflection;
 using NewLife.Web;
 using XCode.Membership;
 
@@ -142,6 +140,7 @@ namespace NewLife.Cube.Controllers
 
                 // 标记登录提供商
                 Session["Cube_Sso"] = client.Name;
+                Session["Cube_Sso_Client"] = client;
 
                 if (!returnUrl.IsNullOrEmpty()) return Redirect(returnUrl);
 
@@ -160,23 +159,40 @@ namespace NewLife.Cube.Controllers
         /// </remarks>
         /// <returns></returns>
         [AllowAnonymous]
-        public virtual ActionResult Logout(String name = null)
+        public virtual ActionResult Logout()
         {
-            Provider?.Logout();
+            // 先读Session,待会会清空
+            var client = Session["Cube_Sso_Client"] as OAuthClient;
 
-            var url = Provider?.GetReturnUrl(Request, false);
-            if (url.IsNullOrEmpty()) url = "~/";
+            var prv = Provider;
+            prv?.Logout();
+
+            var url = "";
 
-            //// 准备返回地址
-            //var url = Request["r"];
-            //if (url.IsNullOrEmpty()) url = "/";
-            //if (!url.StartsWithIgnoreCase("http")) url = new Uri(Request.Url, url).ToString();
+            // 准备跳转到验证中心
+            if (client != null)
+            {
+                if (!client.LogoutUrl.IsNullOrEmpty())
+                {
+                    // 准备返回地址
+                    url = Request["r"];
+                    if (url.IsNullOrEmpty()) url = prv.SuccessUrl;
 
-            //// 准备跳转到验证中心
-            //if (!name.IsNullOrEmpty())
-            //{
+                    var state = Request["state"];
+                    if (!state.IsNullOrEmpty())
+                        state = client.Name + "_" + state;
+                    else
+                        state = client.Name;
 
-            //}
+                    // 跳转到验证中心注销地址
+                    url = client.Logout(url, state, Request.GetRawUrl());
+
+                    return Redirect(url);
+                }
+            }
+
+            url = Provider?.GetReturnUrl(Request, false);
+            if (url.IsNullOrEmpty()) url = "~/";
 
             return Redirect(url);
         }