.Net WebAPI程序集成CAS单点登录-API方式(不使用DotNetCasClient)

以下是ashx一般处理程序的示例,且cas登录单独放到了一个按钮中:

1、登录按钮(js) - 实现2.重定向到Service

        console.log("cos登录");

        var originStr = window.location.origin;
        window.location.href = "https://cas.your.com/cas/login?service=" + originStr + "/WebUI/Admin";

2、登出按钮(js) - 登出cas

function loginOut() {
        $scope.closeAllTabs();
        var para = { "action": "logout" };  // 原来的登出接口
        $.ajax({
            url: ENV.ApiUrl + "bg_user_login.ashx",
            type: "post",
            data: para,
            dataType: "json",
            success: function (result) {
                if (result.success) {
                    $rootScope.loginflag = false;
                    window.sessionStorage["islogin"] = false;
                    window.sessionStorage["userid"] = "";
                    $rootScope.initIndex();
                    $timeout(function () {
                        if (window.sessionStorage["iscaslogin"] === "true") {  // 是cas登录的用户 走cas登出的逻辑
                            var originStr = window.location.origin;
                            window.location.href = "https://cas.your.com/cas/logout?service=" + originStr + "/WebUI/Admin";
                        }
                        else {  // 不是的走原来的逻辑
                            $state.go("tabs.login");
                        }
                    }, 500);
                }
                else {
                    $.show_warning("提示", result.msg);
                }
            }
        })
    };

3、登录页初始化方法的代码 - 实现‘1.访问Cas Client’或‘cas登录’

    function init() {
        //#region CAS 第二版
        var href = window.location.href;

        // http://localhost:8098/WebUI/Admin/?ticket=ST-AS#/tabs/login
        if (href.indexOf("ticket") === -1) {
            // 原登录页面的逻辑
        }
        else {
            console.log("cos登录后自动登录MES");

            // 取ticket
            var ticketStr = href;
            ticketStr = ticketStr.replace("#/tabs/default", "");
            ticketStr = ticketStr.replace("#/tabs/login", "");
            ticketStr = ticketStr.split("ticket=")[1];

            $scope.loading();
            
            var hostName1 = window.location.origin;

            http.isPost = false;
            http.Parameter = {
                action: "login_COS",  // CAS登录接口
                serviceHost: hostName1,
                ticket: ticketStr
            };
            
            http.url = "bg_user_login.ashx";
            return http.go().then(function (response) {
                $scope.hideloading();

                if (response.data.success) {
                    window.sessionStorage["iscaslogin"] = true;
                    window.sessionStorage["islogin"] = true;
                    window.sessionStorage["userid"] = response.data.userid;
                    $rootScope.initIndex();

                    //$state.go("tabs.default");
                    window.location.href = window.location.href.replace("?ticket="+ticketStr,"#/tabs/default");  // ?ticket=ST-AS
                } else {
                    window.sessionStorage["iscaslogin"] = false;
                    window.sessionStorage["islogin"] = false;
                    window.sessionStorage["userid"] = "";
                    alert(response.data.msg);
                }
            }, function (error) {
                window.sessionStorage["iscaslogin"] = false;
                window.sessionStorage["islogin"] = false;
                window.sessionStorage["userid"] = "";
                alert(error.data);
            })
        }
        //#endregion CAS 第二版
    }

    //init();

4、CAS登录接口 - 实现‘5.验证Service,Ticket’和‘6.返回usename’

  #region 手搓Cos SSO
  // 获取用户casTicket
  string serviceStr = context.Request.Params["serviceHost"];  // casTicket
  string ticketStr = context.Request.Params["ticket"];  // casTicket
  if (string.IsNullOrEmpty(serviceStr))
  {
      context.Response.Write("{\"msg\":\"登录参数[serviceHost]丢失,请检查网页完整性!\",\"success\":false}");  // 改成自己的逻辑
  }
  else if (string.IsNullOrEmpty(ticketStr))
  {
      context.Response.Write("{\"msg\":\"登录参数[ticket]丢失,请检查网页完整性!\",\"success\":false}");  // 改成自己的逻辑
  }
  else
  {
      // https://cas.your.com/cas/serviceValidate?service=http://localhost:8098/WebUI/Admin&ticket=
      string tokenValid_Url = "https://cas.your.com/cas/serviceValidate?" +
      //"service=http://" + serviceStr + "/WebUI/Admin" +
      "service=" + serviceStr + "/WebUI/Admin" +
      "&ticket=" + ticketStr;

      // 验证casTicket是否有效
      CasAuthorizeHelper.CasResult casResult = CasAuthorizeHelper.IsTokenValid_API(tokenValid_Url);
      if (!casResult.Success)
      {
          context.Response.Write("{\"msg\":\"" + casResult.Msg + "\",\"success\":false}");  // 改成自己的逻辑
      }
      else
      {
          // casTicket有效,存储用户信息到Cookie
          string userId = casResult.Data.ToString();

          DateTime dateCookieExpires = DateTime.Now.AddDays(7);  // 默认7天

          List<Model.User> users = new BLL.User().GetUsersByUserId(userId);
          if (users.Count < 1)
          {
              // MES系统中无该用户的信息,请联系MES系统管理员进行添加!   // 改成自己的逻辑
              context.Response.Write("{\"msg\":\"MES系统中无该用户的信息,请联系MES系统管理员进行添加!\",\"success\":false}");
          }
          else if (users.Count > 1)
          {
              // MES系统中存在多个同工号用户,请联系MES系统管理员处理!   // 改成自己的逻辑
              context.Response.Write("{\"msg\":\"MES系统中存在多个同工号用户,请联系MES系统管理员处理!\",\"success\":false}");
          }
          else if (users[0].IsAble == 0)
          {
              context.Response.Write("{\"msg\":\"用户已被禁用!\",\"success\":false}");  // 改成自己的逻辑
          }
          else
          {
              // 改成自己的逻辑
              FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
                 2, users[0].UserId, DateTime.Now, dateCookieExpires, false,
                 new JavaScriptSerializer().Serialize(users[0])  //序列化当前用户对象
              );
              string encTicket = FormsAuthentication.Encrypt(ticket);
              HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
              if (dateCookieExpires != new DateTime(9999, 12, 31))    //不是默认时间才设置过期时间,否则会话cookie(先保留该逻辑)
                  cookie.Expires = dateCookieExpires;
              context.Response.Cookies.Add(cookie);

              context.Response.Write("{\"msg\":\"登录成功!\",\"userid\":\"" + users[0].UserId + "\",\"success\":true}");  // 改成自己的逻辑
          }
      }
  }
  #endregion 手搓Cos SSO

5、CasAuthorizeHelper

//using DotNetCasClient;
using System;
using System.Net.Http;

namespace Test
{
    /// <summary>
    /// Cas SSO帮助类
    /// </summary>
    public static class CasAuthorizeHelper
    {
        #region DotNetCasClient的功能
        ///// <summary>
        ///// 从Cookie获取Cas凭证
        ///// </summary>
        ///// <returns></returns>
        //public static CasAuthenticationTicket GetCasAuthorizeTicket()
        //{
        //    CasAuthenticationTicket casTicket = null;
        //    var ticketCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];

        //    if (ticketCookie != null && !string.IsNullOrWhiteSpace(ticketCookie.Value))
        //    {
        //        var ticket = FormsAuthentication.Decrypt(ticketCookie.Value);

        //        if (ticket != null && CasAuthentication.ServiceTicketManager != null)
        //        {
        //            casTicket = CasAuthentication.ServiceTicketManager.GetTicket(ticket.UserData);
        //        }
        //    }
        //    return casTicket;
        //}

        ///// <summary>
        ///// 从Cookie获取Cas凭证
        ///// </summary>
        ///// <param name="request"></param>
        ///// <returns></returns>
        //public static CasAuthenticationTicket GetCasAuthorizeTicket(this HttpRequestBase request)
        //{
        //    CasAuthenticationTicket casTicket = null;
        //    var ticketCookie = request.Cookies[FormsAuthentication.FormsCookieName];

        //    if (ticketCookie != null && !string.IsNullOrWhiteSpace(ticketCookie.Value))
        //    {
        //        var ticket = FormsAuthentication.Decrypt(ticketCookie.Value);
        //        if (ticket != null && CasAuthentication.ServiceTicketManager != null)
        //        {
        //            casTicket = CasAuthentication.ServiceTicketManager.GetTicket(ticket.UserData);

        //            //记录登录用户Ticket消息明细信息
        //            //LogUtil.Info("ticket:{0},获取CAS用户认证信息:{1}", ticket.UserData, SerializerUtil.ToJson(casTicket));
        //        }
        //    }
        //    return casTicket;
        //}

        ///// <summary>
        ///// 验证Cas凭证是否有效
        ///// </summary>
        ///// <param name="ticket"></param>
        ///// <returns></returns>
        //public static bool IsTokenValid(CasAuthenticationTicket ticket)
        //{
        //    if (ticket == null) return false;
        //    return CasAuthentication.ServiceTicketManager.VerifyClientTicket(ticket);
        //}

        ///// <summary>
        ///// 清理Cas凭证
        ///// </summary>
        //public static void ClearAuthCookie()
        //{
        //    CasAuthentication.ClearAuthCookie();
        //}
        #endregion DotNetCasClient的功能

        #region 手搓Cas SSO
        /// <summary>
        /// 验证Cas凭证是否有效
        /// </summary>
        /// <param name="tokenValid_Url">验证凭证的地址</param>
        /// <returns></returns>
        public static CasAuthorizeHelper.CasResult IsTokenValid_API(string tokenValid_Url)
        {
            CasResult casResult = new CasResult();

            try
            {
                Uri uri = new Uri(tokenValid_Url);

                HttpResponseMessage response = new HttpClient().GetAsync(uri).Result;
                if (response.IsSuccessStatusCode)  // 调用成功
                {
                    string content = response.Content.ReadAsStringAsync().Result;

                    // 正常:
                    ////<cas:serviceResponse xmlns:cas="1">
                    ////<cas:authenticationSuccess>
                    ////<cas:user></cas:user>
                    ////</cas:authenticationSuccess>
                    ////</cas:serviceResponse>
                    // null:
                    ////<cas:serviceResponse xmlns:cas="1">
                    ////  <cas:authenticationFailure code="INVALID_TICKET">未能够识别出目标 'SVAS'票根</cas:authenticationFailure>
                    ////</cas:serviceResponse>
                    if (string.IsNullOrEmpty(content))
                    {
                        // 凭证验证异常
                        casResult.Success = false;
                        casResult.Msg = string.Concat("通过API校验Cas凭证失败!报文为空!");
                    }

                    string[] contentLine = content.Split('\n');

                    if (contentLine.Length<3)
                    {
                        // 凭证验证异常
                        casResult.Success = false;
                        casResult.Msg = string.Concat("通过API校验Cas凭证失败!报文异常!"+ content);
                    }

                    if (contentLine[1].Contains("authenticationFailure") && contentLine[1].Contains("未能够识别出目标"))
                    {
                        // 凭证无效
                        casResult.Success = false;
                        casResult.Msg = "CAS凭证无效!请刷新页面重新登录!";
                    }
                    else if (contentLine[1].Contains("authenticationSuccess"))
                    {
                        // 凭证有效
                        casResult.Success = true;

                        string userNameStr = contentLine[2];
                        userNameStr = userNameStr.Replace("<cas:user>", "");
                        userNameStr = userNameStr.Replace("</cas:user>", "");
                        casResult.Data = userNameStr.Trim();
                    }
                    else
                    {
                        // 凭证验证异常
                        casResult.Success = false;
                        casResult.Msg = string.Concat("通过API校验Cas凭证失败!报文异常!" + content);
                    }
                }
                else
                {
                    casResult.Success = false;

                    string conStr = response.Content.ReadAsStringAsync()?.Result ?? string.Empty;

                    casResult.Msg = string.Concat("通过API校验Cas凭证失败![", response.StatusCode.ToString(), "]", conStr);
                }
            }
            catch (Exception ex)
            {
                //Debug.WriteLine(@"\tERROR {0}", ex.Message);

                casResult.Success = false;
                casResult.Msg = "通过API校验Cas凭证失败!" + ex.Message;
            }

            return casResult;
        }

        /// <summary>
        /// Cas用方法结果类
        /// </summary>
        public class CasResult
        {
            public bool Success { get; set; }

            public string Msg { get; set; } = string.Empty;

            public object Data { get; set; }

            public object Obj1 { get; set; }
        }
        #endregion 手搓Cas
    }
}

 

posted @   ꧁执笔小白꧂  阅读(111)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
历史上的今天:
2020-04-23 在 Windows 上安装 SQLite及工具笔记
2020-04-23 VS安装Halcon插件
点击右上角即可分享
微信分享提示