go cas实现

根据php cas的ticket验证原理实现了一个go版本的,主要就是判断用户访问的URL中是否带ticket,如果否就直接重定向到CAS认证中心进行登录;如果带有ticket,也要到CAS认证中心去认证ticket的有效性,如果有效,则可以正常访问当前网页,否则重定向到认证中心的登录页面。以下为实现代码:

package cas

import (
	"io/ioutil"
	"net/http"
	"strings"
)

/*
判断当前访问是否已认证
 */
func IsAuthentication(w http.ResponseWriter, r *http.Request, casServerUrl string) bool {
	if !hasTicket(r) {
		redirectToCasServer(w, r, casServerUrl)
		return false
	}

	localUrl := getLocalUrl(r)
	if !validateTicket(localUrl, casServerUrl) {
		redirectToCasServer(w, r, casServerUrl)
		return false
	}
	return true
}

/*
重定向到CAS认证中心
 */
func redirectToCasServer(w http.ResponseWriter, r *http.Request, casServerUrl string) {
	casServerUrl = casServerUrl + "/login?service=" + getLocalUrl(r)
	http.Redirect(w, r, casServerUrl, http.StatusFound)
}

/*
验证访问路径中的ticket是否有效
 */
func validateTicket(localUrl, casServerUrl string) bool {
	casServerUrl = casServerUrl + "/serviceValidate?service=" + localUrl
	res, err := http.Get(casServerUrl)
	if err != nil {
		return false
	}
	defer res.Body.Close()

	data, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return false
	}

	dataStr := string(data)
	if !strings.Contains(dataStr, "cas:authenticationSuccess") {
		return false
	}
	return true
}

/*
从请求中获取访问路径
 */
func getLocalUrl(r *http.Request) string {
	scheme := "http://"
	if r.TLS != nil {
		scheme = "https://"
	}
	url := strings.Join([]string{scheme, r.Host, r.RequestURI}, "")
	slice := strings.Split(url, "?")
	if len(slice) > 1 {
		localUrl := slice[0]
		urlParamStr := ensureOneTicketParam(slice[1])
		url = localUrl + "?" + urlParamStr
	}
	return url
}

/*
处理并确保路径中只有一个ticket参数
 */
func ensureOneTicketParam(urlParams string) string {
	if len(urlParams) == 0 || !strings.Contains(urlParams, "ticket") {
		return urlParams
	}

	sep := "&"
	params := strings.Split(urlParams, sep)

	newParams := ""
	ticket := ""
	for _, value := range params {
		if strings.Contains(value, "ticket") {
			ticket = value
			continue
		}

		if len(newParams) == 0 {
			newParams = value
		} else {
			newParams = newParams + sep + value
		}

	}
	newParams = newParams + sep + ticket
	return newParams
}

/*
获取ticket
 */
func getTicket(r *http.Request) string {
	return r.FormValue("ticket")
}

/*
判断是否有ticket
 */
func hasTicket(r *http.Request) bool {
	t := getTicket(r)
	return len(t) != 0
}


对于每个用户请求,直接调用IsAuthentication即可。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值