func acsService(w http.ResponseWriter, r *http.Request) (err error) { defer r.Body.Close() birk, err := r.Cookie("BIRK") if err != nil { return err } // to-do: check hmac // we checked the request when we received in birkService - we can use it without fear request, err := gosaml.DecodeSAMLMsg(birk.Value, true) sp_md, err := hub_ops.MDQ(request.Query1(nil, "/samlp:AuthnRequest/saml:Issuer")) // spmd, _, err := edugain.MDQ(request.Query1(nil, "/samlp:AuthnRequest/saml:Issuer")) //http.SetCookie(w, &http.Cookie{Name: "BIRK", Value: "", MaxAge: -1, Domain: config["HYBRID_DOMAIN"], Path: "/", Secure: true, HttpOnly: true}) response, idp_md, _, err := gosaml.GetSAMLMsg(r, "SAMLResponse", hub_ops, hub, hubmd) if err != nil { return } hub_md := gosaml.NewXp(Wayfrequestedattributes) err = WayfAttributeHandler(idp_md, hub_md, sp_md, response) if err != nil { return } birkmd, err := edugain.MDQ(request.Query1(nil, "@Destination")) nameid := response.Query(nil, "./saml:Assertion/saml:Subject/saml:NameID")[0] // respect nameID in req, give persistent id + all computed attributes + nameformat conversion nameidformat := sp_md.Query1(nil, "./md:SPSSODescriptor/md:NameIDFormat") if nameidformat == persistent { response.QueryDashP(nameid, "@Format", persistent, nil) eptid := response.Query1(nil, `./saml:Assertion/saml:AttributeStatement/saml:Attribute[@FriendlyName="eduPersonTargetedID"]/saml:AttributeValue`) response.QueryDashP(nameid, ".", eptid, nil) } else if nameidformat == transient { response.QueryDashP(nameid, ".", gosaml.Id(), nil) } newresponse := gosaml.NewResponse(stdtiming.Refresh(), birkmd, sp_md, request, response) for _, q := range elementsToSign { err = gosaml.SignResponse(newresponse, q, birkmd) if err != nil { return } } // when consent as a service is ready - we will post to that acs := newresponse.Query1(nil, "@Destination") data := formdata{Acs: acs, Samlresponse: base64.StdEncoding.EncodeToString([]byte(newresponse.X2s()))} postform.Execute(w, data) return }
func kribService(w http.ResponseWriter, r *http.Request) (err error) { defer r.Body.Close() response, _, _, err := gosaml.GetSAMLMsg(r, "SAMLResponse", edugain, edugain, nil) if err != nil { return } destination := debify.ReplaceAllString(response.Query1(nil, "@Destination"), "$1$2") response.QueryDashP(nil, "@Destination", destination, nil) response.QueryDashP(nil, "./saml:Assertion/saml:Subject/saml:SubjectConfirmation/saml:SubjectConfirmationData/@Recipient", destination, nil) issuer := config["HYBRID_HUB"] response.QueryDashP(nil, "./saml:Issuer", issuer, nil) response.QueryDashP(nil, "./saml:Assertion/saml:Issuer", issuer, nil) // Krib always receives attributes with nameformat=urn. Before sending to the real SP we need to look into // the metadata for SP to determine the actual nameformat - as WAYF supports both for internal SPs. mdsp, err := hub_ops.MDQ(destination) if err != nil { return } requestedattributes := mdsp.Query(nil, "./md:SPSSODescriptor/md:AttributeConsumingService/md:RequestedAttribute") attributestatement := response.Query(nil, "./saml:Assertion/saml:AttributeStatement")[0] for _, attr := range requestedattributes { if attr.GetAttr("NameFormat") == basic { basicname := attr.GetAttr("Name") uriname := basic2uri[basicname] responseattribute := response.Query(attributestatement, "saml:Attribute[@Name='"+uriname+"']") if len(responseattribute) > 0 { responseattribute[0].SetAttr("Name", basicname) responseattribute[0].SetAttr("NameFormat", basic) } } } mdhub, err := hub.MDQ(config["HYBRID_HUB"]) if err != nil { return } for _, q := range elementsToSign { err = gosaml.SignResponse(response, q, mdhub) if err != nil { return } } data := formdata{Acs: destination, Samlresponse: base64.StdEncoding.EncodeToString([]byte(response.X2s()))} postform.Execute(w, data) return }
func ssoService(w http.ResponseWriter, r *http.Request) (err error) { defer r.Body.Close() // handle non ok urls gracefully // var err error // check issuer and acs in md // receiveRequest -> request, issuer md, receiver md // check for IDPList 1st in md, then in request then in query // sanitize idp from query or request request, spmd, _, err := gosaml.GetSAMLMsg(r, "SAMLRequest", hub_ops, hub, nil) if err != nil { return } idp := spmd.Query1(nil, "IDPList/ProviderID") // Need to find a place for IDPList if idp == "" { idp = request.Query1(nil, "IDPList/ProviderID") } if idp == "" { idp = r.URL.Query().Get("idpentityid") } if idp == "" { data := url.Values{} data.Set("return", "https://"+r.Host+r.RequestURI) data.Set("returnIDParam", "idpentityid") http.Redirect(w, r, config["HYBRID_DISCOVERY"]+data.Encode(), http.StatusFound) } else { var idpmd *gosaml.Xp acs := request.Query1(nil, "@AssertionConsumerServiceURL") acsurl := bify.ReplaceAllString(acs, "${1}wayf.wayf.dk/krib.php/$2") request.QueryDashP(nil, "@AssertionConsumerServiceURL", acsurl, nil) idpmd, err = edugain.MDQ(idp) if err != nil { return } const ssoquery = "./md:IDPSSODescriptor/md:SingleSignOnService[@Binding='urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect']/@Location" ssoservice := idpmd.Query1(nil, ssoquery) if ssoservice == "" { } request.QueryDashP(nil, "@Destination", ssoservice, nil) u, _ := gosaml.SAMLRequest2Url(request, "", "", "") http.Redirect(w, r, u.String(), http.StatusFound) } return }
func birkService(w http.ResponseWriter, r *http.Request) (err error) { defer r.Body.Close() // get the sp as well to check for allowed acs req, _, mdbirkidp, err := gosaml.GetSAMLMsg(r, "SAMLRequest", edugain, edugain, nil) if err != nil { return } // Save the request in a cookie for when the response comes back cookievalue := base64.StdEncoding.EncodeToString(gosaml.Deflate(req.X2s())) http.SetCookie(w, &http.Cookie{Name: "BIRK", Value: cookievalue, Domain: config["HYBRID_DOMAIN"], Path: "/", Secure: true, HttpOnly: true}) idp := debify.ReplaceAllString(mdbirkidp.Query1(nil, "@entityID"), "$1$2") mdidp, err := hub_ops.MDQ(idp) mdhub, err := hub.MDQ(config["HYBRID_HUB"]) // use a std request - we take care of NameID etc in acsService below newrequest := gosaml.NewAuthnRequest(stdtiming.Refresh(), mdhub, mdidp) // to-do delete the following line when md for the hub is OK newrequest.QueryDashP(nil, "@AssertionConsumerServiceURL", config["HYBRID_HUB"]+config["HYBRID_ACS"], nil) u, _ := gosaml.SAMLRequest2Url(newrequest, "", "", "") // not signed so blank key, pw and algo http.Redirect(w, r, u.String(), http.StatusFound) return }