go cas实现

来源:互联网 发布:我比想象中爱你 js 编辑:程序博客网 时间:2024/06/11 01:26

这是之前实现的一个代码,觉得golang很有意思,虽然由于各种原因无法在工作中使用,但还是喜欢并去学习,思考怎么解决实际应用中的问题。工作中有使用过php CAS,然后根据php cas的ticket验证原理实现了一个go版本的,主要就是判断用户访问的URL中是否带ticket,如果否就直接重定向到CAS认证中心进行登录;如果带有ticket,也要到CAS认证中心去认证ticket的有效性,如果有效,则可以正常访问当前网页,否则重定向到认证中心的登录页面。以下为实现代码:

package casimport (    "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即可。

原创粉丝点击