func main() { port := flag.String("port", "14000", "Port number to listen on") backend_url := flag.String("backend", "http://localhost:14001/authenticate", "Address of the authentication backend") flag.Parse() config := osin.NewServerConfig() config.AllowGetAccessRequest = true config.AllowClientSecretInParams = true storage := NewInMemoryStorage() load_clients(storage) server := osin.NewServer(config, storage) // Authorization code endpoint http.HandleFunc("/authorize", func(w http.ResponseWriter, r *http.Request) { resp := server.NewResponse() if ar := server.HandleAuthorizeRequest(resp, r); ar != nil { if !HandleLoginPage(*backend_url, resp, ar, w, r) { return } ar.Authorized = true server.FinishAuthorizeRequest(resp, r, ar) } if resp.IsError && resp.InternalError != nil { fmt.Printf("ERROR: %s\n", resp.InternalError) } osin.OutputJSON(resp, w, r) }) // Access token endpoint http.HandleFunc("/token", func(w http.ResponseWriter, r *http.Request) { resp := server.NewResponse() if ar := server.HandleAccessRequest(resp, r); ar != nil { ar.Authorized = true server.FinishAccessRequest(resp, r, ar) } if resp.IsError && resp.InternalError != nil { fmt.Printf("ERROR: (internal) %s\n", resp.InternalError) } osin.OutputJSON(resp, w, r) }) // Information endpoint http.HandleFunc("/info", func(w http.ResponseWriter, r *http.Request) { resp := server.NewResponse() if ir := server.HandleInfoRequest(resp, r); ir != nil { server.FinishInfoRequest(resp, r, ir) } osin.OutputJSON(resp, w, r) }) fs := http.FileServer(http.Dir("assets")) http.Handle("/assets/", http.StripPrefix("/assets/", fs)) http.ListenAndServe(":"+*port, nil) }
func GET_info(w http.ResponseWriter, r *http.Request, s *osin.Server) { resp := s.NewResponse() if ir := s.HandleInfoRequest(resp, r); ir != nil { s.FinishInfoRequest(resp, r, ir) } osin.OutputJSON(resp, w, r) }
func (s *server) handleToken(w http.ResponseWriter, r *http.Request) { resp := s.oauthServer.NewResponse() defer resp.Close() if ar := s.oauthServer.HandleAccessRequest(resp, r); ar != nil { switch ar.Type { case osin.AUTHORIZATION_CODE: ar.Authorized = true case osin.REFRESH_TOKEN: ar.Authorized = true case osin.PASSWORD: if ar.Username == "test" && ar.Password == "test" { ar.Authorized = true } case osin.CLIENT_CREDENTIALS: ar.Authorized = true } s.oauthServer.FinishAccessRequest(resp, r, ar) } if resp.IsError && resp.InternalError != nil { fmt.Printf("ERROR: %s\n", resp.InternalError) } // if !resp.IsError { // resp.Output["custom_parameter"] = 19923 // } osin.OutputJSON(resp, w, r) }
// Info return the token's information via http func Info(w http.ResponseWriter, r *http.Request) { var ( server = OAuthComponent(r) resp = server.NewResponse() ) defer resp.Close() if ir := server.HandleInfoRequest(resp, r); ir != nil { // don't process if is already an error if resp.IsError { return } // output data resp.Output["client_id"] = ir.AccessData.Client.GetId() // resp.Output["access_token"] = ir.AccessData.AccessToken resp.Output["token_type"] = server.Config.TokenType resp.Output["expires_in"] = ir.AccessData.CreatedAt.Add(time.Duration(ir.AccessData.ExpiresIn)*time.Second).Sub(server.Now()) / time.Second if ir.AccessData.RefreshToken != "" { resp.Output["refresh_token"] = ir.AccessData.RefreshToken } if ir.AccessData.Scope != "" { resp.Output["scope"] = ir.AccessData.Scope } if ir.AccessData.UserData != nil { resp.Output["owner"] = ir.AccessData.UserData.(string) } } //Right here retry with the session. osin.OutputJSON(resp, w, r) }
// Token is the action of Get /oauth2/token func Token() echo.HandlerFunc { return func(c echo.Context) error { resp := oauth.NewResponse() defer resp.Close() if ar := oauth.HandleAccessRequest(resp, c.Request()); ar != nil { switch ar.Type { case osin.AUTHORIZATION_CODE: ar.Authorized = true case osin.REFRESH_TOKEN: ar.Authorized = true case osin.PASSWORD: if _, err := nerdz.Login(ar.Username, ar.Password); err == nil { ar.Authorized = true } case osin.CLIENT_CREDENTIALS: ar.Authorized = true } oauth.FinishAccessRequest(resp, c.Request(), ar) } if resp.IsError && resp.InternalError != nil { return c.JSON(http.StatusInternalServerError, &rest.Response{ HumanMessage: "Internal Server error", Message: resp.InternalError.Error(), Status: http.StatusBadRequest, Success: false, }) } return osin.OutputJSON(resp, c.Response(), c.Request()) } }
func (o *Oauth) AuthorizeClient(w http.ResponseWriter, r *http.Request) { server := oauth.server resp := server.NewResponse() if ar := server.HandleAuthorizeRequest(resp, r); ar != nil { session, err := getSession(r) if err != nil { w.WriteHeader(http.StatusNotFound) return } // Handle the login page // if !example.HandleLoginPage(ar, w, r) { // return // } // ~to-do , needs to be added users data ar.UserData = session.Username ar.Authorized = true server.FinishAuthorizeRequest(resp, r, ar) } if resp.IsError && resp.InternalError != nil { w.WriteHeader(http.StatusInternalServerError) return } if !resp.IsError { resp.Output["custom_parameter"] = 187723 return } osin.OutputJSON(resp, w, r) }
func (cz *Citizens) Login(auth *osin.Server) gin.HandlerFunc { return func(c *gin.Context) { // see https://github.com/RangelReale/osin/blob/master/example/complete/complete.go#L45 res := auth.NewResponse() if aReq := auth.HandleAccessRequest(res, c.Request); aReq != nil { // check username/password user := &models.User{} // find in DB err := cz.Connection.Collection(COL_CITIZEN).FindOne(bson.M{"username": aReq.Username}, user) // user found and has valid username/password if err == nil && user.ValidCredentials(aReq.Username, aReq.Password) { aReq.Authorized = true // save user data along with the access token aReq.UserData = gin.H{"username": user.UserName} } // creates the response automatically with error message and code auth.FinishAccessRequest(res, c.Request, aReq) } if res.IsError && res.InternalError != nil { fmt.Printf("ACCESS_ERROR: %s\n", res.InternalError) } osin.OutputJSON(res, c.Writer, c.Request) } }
func NewOAuth2(base string) *OAuth2 { cfg := osin.NewServerConfig() cfg.AllowGetAccessRequest = true server := osin.NewServer(cfg, example.NewTestStorage()) funcauthorize := func(w http.ResponseWriter, r *http.Request, params httprouter.Params) { resp := server.NewResponse() defer resp.Close() if ar := server.HandleAuthorizeRequest(resp, r); ar != nil { if !example.HandleLoginPage(ar, w, r) { return } ar.Authorized = true server.FinishAuthorizeRequest(resp, r, ar) } if resp.IsError && resp.InternalError != nil { fmt.Printf("ERROR: %s\n", resp.InternalError) } osin.OutputJSON(resp, w, r) } functoken := func(w http.ResponseWriter, r *http.Request, params httprouter.Params) { resp := server.NewResponse() defer resp.Close() if ar := server.HandleAccessRequest(resp, r); ar != nil { ar.Authorized = true server.FinishAccessRequest(resp, r, ar) } if resp.IsError && resp.InternalError != nil { fmt.Printf("ERROR: %s\n", resp.InternalError) } osin.OutputJSON(resp, w, r) } o := &OAuth2{ FuncAuthorize: funcauthorize, FuncToken: functoken, Router: httprouter.New(), BaseURI: base, } o.InitRouter() return o }
// Information endpoint func (oauth *oAuthHandler) HandleInfo(w http.ResponseWriter, r *http.Request) { server := oauth.server resp := server.NewResponse() if ir := server.HandleInfoRequest(resp, r); ir != nil { server.FinishInfoRequest(resp, r, ir) } osin.OutputJSON(resp, w, r) }
func (h *Handler) TokenHandler(w http.ResponseWriter, r *http.Request) { resp := h.server.NewResponse() r.ParseForm() defer resp.Close() if ar := h.server.HandleAccessRequest(resp, r); ar != nil { switch ar.Type { case osin.AUTHORIZATION_CODE: data, ok := ar.UserData.(string) if !ok { http.Error(w, fmt.Sprintf("Could not assert UserData to string: %v", ar.UserData), http.StatusInternalServerError) return } var claims jwt.ClaimsCarrier if err := json.Unmarshal([]byte(data), &claims); err != nil { http.Error(w, fmt.Sprintf("Could not unmarshal UserData: %v", ar.UserData), http.StatusInternalServerError) return } ar.UserData = jwt.NewClaimsCarrier(uuid.New(), claims.GetSubject(), h.Issuer, h.Audience, time.Now(), time.Now()) ar.Authorized = true case osin.REFRESH_TOKEN: data, ok := ar.UserData.(map[string]interface{}) if !ok { http.Error(w, fmt.Sprintf("Could not assert UserData type: %v", ar.UserData), http.StatusInternalServerError) return } claims := jwt.ClaimsCarrier(data) ar.UserData = jwt.NewClaimsCarrier(uuid.New(), claims.GetSubject(), h.Issuer, h.Audience, time.Now(), time.Now()) ar.Authorized = true case osin.PASSWORD: // TODO if !ar.Client.isAllowedToAuthenticateUser // TODO ... return // TODO } if user, err := h.authenticate(w, r, ar.Username, ar.Password); err == nil { ar.UserData = jwt.NewClaimsCarrier(uuid.New(), user.GetID(), h.Issuer, h.Audience, time.Now(), time.Now()) ar.Authorized = true } case osin.CLIENT_CREDENTIALS: ar.UserData = jwt.NewClaimsCarrier(uuid.New(), ar.Client.GetId(), h.Issuer, h.Audience, time.Now(), time.Now()) ar.Authorized = true // TODO ASSERTION workflow http://leastprivilege.com/2013/12/23/advanced-oauth2-assertion-flow-why/ // TODO Since assertions are only a draft for now and there is no need for SAML or similar this is postponed. //case osin.ASSERTION: // if ar.AssertionType == "urn:hydra" && ar.Assertion == "osin.data" { // ar.Authorized = true // } } h.server.FinishAccessRequest(resp, r, ar) } if resp.IsError { resp.StatusCode = http.StatusUnauthorized } osin.OutputJSON(resp, w, r) }
func GET_token(w http.ResponseWriter, r *http.Request, s *osin.Server) { resp := s.NewResponse() if ar := s.HandleAccessRequest(resp, r); ar != nil { // always true ar.Authorized = true s.FinishAccessRequest(resp, r, ar) } osin.OutputJSON(resp, w, r) }
func (s *Server) handleInfo(w http.ResponseWriter, r *http.Request) { resp := s.server.NewResponse() defer resp.Close() if ir := s.server.HandleInfoRequest(resp, r); ir != nil { s.server.FinishInfoRequest(resp, r, ir) } osin.OutputJSON(resp, w, r) }
func handleAuthorization(w http.ResponseWriter, r *http.Request) { resp := server.NewResponse() defer resp.Close() if ar := server.HandleAuthorizeRequest(resp, r); ar != nil { if !example.HandleLoginPage(ar, w, r) { return } ar.Authorized = true scopes := make(map[string]bool) for _, s := range strings.Fields(ar.Scope) { scopes[s] = true } // If the "openid" connect scope is specified, attach an ID Token to the // authorization response. // // The ID Token will be serialized and signed during the code for token exchange. if scopes["openid"] { // These values would be tied to the end user authorizing the client. now := time.Now() idToken := IDToken{ Issuer: issuer, UserID: "id-of-test-user", ClientID: ar.Client.GetId(), Expiration: now.Add(time.Hour).Unix(), IssuedAt: now.Unix(), Nonce: r.URL.Query().Get("nonce"), } if scopes["profile"] { idToken.Name = "Jane Doe" idToken.GivenName = "Jane" idToken.FamilyName = "Doe" idToken.Locale = "us" } if scopes["email"] { t := true idToken.Email = "*****@*****.**" idToken.EmailVerified = &t } // NOTE: The storage must be able to encode and decode this object. ar.UserData = &idToken } server.FinishAuthorizeRequest(resp, r, ar) } if resp.IsError && resp.InternalError != nil { log.Printf("internal error: %v", resp.InternalError) } osin.OutputJSON(resp, w, r) }
func (oauth *OAuth) Token(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { fmt.Println("Token:\r\n") resp := oauth.Server.NewResponse() defer resp.Close() if ar := oauth.Server.HandleAccessRequest(resp, r); ar != nil { checkAccessRequest(oauth, w, r, ar) oauth.Server.FinishAccessRequest(resp, r, ar) } osin.OutputJSON(resp, w, r) }
// OAuth2 information endpoint func (o *Api) info(w http.ResponseWriter, r *http.Request) { log.Println(OAUTH2_API_PREFIX, "OAuthApi: info") resp := o.oauthServer.NewResponse() defer resp.Close() if ir := o.oauthServer.HandleInfoRequest(resp, r); ir != nil { o.oauthServer.FinishInfoRequest(resp, r, ir) } osin.OutputJSON(resp, w, r) }
// Info is the action of GET /oauth2/info func Info() echo.HandlerFunc { return func(c echo.Context) error { resp := oauth.NewResponse() defer resp.Close() if ir := oauth.HandleInfoRequest(resp, c.Request()); ir != nil { oauth.FinishInfoRequest(resp, c.Request(), ir) } return osin.OutputJSON(resp, c.Response(), c.Request()) } }
func GET_authorize(c martini.Context, sess sessions.Session, w http.ResponseWriter, r *http.Request, s *osin.Server) { resp := s.NewResponse() if ar := s.HandleAuthorizeRequest(resp, r); ar != nil { if !inner_GET_authorize(c, sess, r, ar) { return } ar.Authorized = true s.FinishAuthorizeRequest(resp, r, ar) } osin.OutputJSON(resp, w, r) }
func (h *Handler) AuthorizeHandler(w http.ResponseWriter, r *http.Request) { resp := h.server.NewResponse() defer resp.Close() if ar := h.server.HandleAuthorizeRequest(resp, r); ar != nil { // For now, a provider must be given. // TODO there should be a fallback provider which is a redirect to the login endpoint. This should be configurable by env var. // Let's see if this is a valid provider. If not, return an error. provider, err := h.Providers.Find(r.URL.Query().Get("provider")) if err != nil { http.Error(w, fmt.Sprintf(`Provider "%s" not known.`, err), http.StatusBadRequest) return } // This could be made configurable with `connection.GetCodeKeyName()` code := r.URL.Query().Get("access_code") if code == "" { // If no code was given we have to initiate the provider's authorization workflow url := provider.GetAuthCodeURL(ar) http.Redirect(w, r, url, http.StatusFound) return } // Create a session by exchanging the code for the auth code connection, err := provider.Exchange(code) if err != nil { http.Error(w, fmt.Sprintf("Could not exchange access code: %s", err), http.StatusUnauthorized) return } subject := connection.GetRemoteSubject() user, err := h.Connections.FindByRemoteSubject(provider.GetID(), subject) if err == account.ErrNotFound { // The subject is not linked to any account. http.Error(w, "Provided token is not linked to any existing account.", http.StatusUnauthorized) return } else if err != nil { // Something else went wrong http.Error(w, fmt.Sprintf("Could assert subject claim: %s", err), http.StatusInternalServerError) return } ar.UserData = jwt.NewClaimsCarrier(uuid.New(), user.GetLocalSubject(), h.Issuer, h.Audience, time.Now(), time.Now()) ar.Authorized = true h.server.FinishAuthorizeRequest(resp, r, ar) } if resp.IsError { resp.StatusCode = http.StatusUnauthorized } osin.OutputJSON(resp, w, r) }
func (o *OAuthHandler) HandleInfo(w http.ResponseWriter, r *http.Request) { server := o.server resp := server.NewResponse() defer resp.Close() if ir := server.HandleInfoRequest(resp, r); ir != nil { server.FinishInfoRequest(resp, r, ir) } if resp.IsError || resp.InternalError != nil { //log.Printf("ERROR: %s\n", resp.InternalError) //unnecessary to report on bad token resp.StatusCode = http.StatusBadRequest } osin.OutputJSON(resp, w, r) }
func handleAuthorize(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err != nil { log.Println("error parsing form", err) } fmt.Printf("r.Form = %+v\n", r.Form) validSess := checkSession(r) if !validSess && (r.Form.Get("username") == "" || r.Form.Get("password") == "") { writeAuthForm(w, r) return } resp := server.NewResponse() defer func() { if resp.IsError && resp.InternalError != nil { fmt.Printf("resp.InternalError = %+v\n", resp.InternalError) } }() defer resp.Close() defer osin.OutputJSON(resp, w, r) log.Println(r) if ar := server.HandleAuthorizeRequest(resp, r); ar != nil { defer server.FinishAuthorizeRequest(resp, r, ar) if validSess { log.Println("authed by session") ar.Authorized = true return } valid, err := validateUser(userPass{r.Form.Get("username"), r.Form.Get("password")}) if err == errExceededAttempts { resp.StatusCode = 420 resp.Output["reason"] = "Authorization attempts exceeded" } if valid { ar.Authorized = true writeSession(w, r.Form.Get("username")) } } }
// Authorization code endpoint func oauthAuthorize(w http.ResponseWriter, r *http.Request, ctx *Context) (err error) { resp := server.NewResponse() defer resp.Close() if ar := server.HandleAuthorizeRequest(resp, r); ar != nil { link := fmt.Sprintf("/authorize?response_type=%s&client_id=%s&redirect_uri=%s&state=%s&scope=%s", ar.Type, ar.Client.GetId(), url.QueryEscape(ar.RedirectUri), ar.State, ar.Scope) // HANDLE LOGIN PAGE HERE if ctx.User == nil { ctx.Referer = link return loginForm(w, r, ctx) // resp.SetRedirect(reverse("login") + "?referer=" + reverse("authorize")) } else { if r.Method == "GET" { scopes, err := backends.LoadScopes() if err != nil { return err } return T("authorize.html").Execute(w, map[string]interface{}{ "link": link, "response_type": ar.Type, "scopes": scopes, "client": ar.Client.(*models.Client), "ctx": ctx, }) } if r.PostForm.Get("authorize") == "1" { ar.UserData = ctx.User.Uid ar.Authorized = true server.FinishAuthorizeRequest(resp, r, ar) } else { resp.SetRedirect(reverse("welcome")) } } } if resp.IsError && resp.InternalError != nil { log.Printf("authorize ERROR: %s\n", resp.InternalError) } // if !resp.IsError { // resp.Output["uid"] = ctx.User.Uid // } debugf("oauthAuthorize resp: %v", resp) osin.OutputJSON(resp, w, r) return resp.InternalError }
func handleSAML(w http.ResponseWriter, r *http.Request) { resp := server.NewResponse() defer resp.Close() defer func() { err := osin.OutputJSON(resp, w, r) if err != nil { log.Println("error finishing authZ request", err) } }() if ar := server.HandleAuthorizeRequest(resp, r); ar != nil { defer server.FinishAuthorizeRequest(resp, r, ar) err := r.ParseForm() if err != nil { log.Println(err) } sr := r.Form.Get("SAMLResponse") bs, err := base64.StdEncoding.DecodeString(sr) if err != nil { log.Println("Error decoding base64", err) } var res saml.Response err = xml.NewDecoder(bytes.NewBuffer(bs)).Decode(&res) if err != nil { log.Println(err) return } pt, err := res.Decrypt(cert) if err != nil { log.Println("error decrypting saml:", err) return } var a saml.Assertion err = xml.NewDecoder(bytes.NewBuffer(pt)).Decode(&a) if err != nil { log.Println(err) return } ar.UserData = a ar.Authorized = true } }
func (c App) Index() revel.Result { r := c.Request.Request w := c.Response.Out resp := server.NewResponse() defer resp.Close() ar := server.HandleAuthorizeRequest(resp, r) ar.Authorized = true server.FinishAuthorizeRequest(resp, r, ar) osin.OutputJSON(resp, w, r) return nil }
//检查token拥有的资源 func (oauth *OAuth) CheckPrivilige(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { resp := oauth.Server.NewResponse() flag := true queryUrl := common.GetUrlParam(r) clientId := queryUrl["client_id"][0] token := queryUrl["token"][0] storage, err := oauth.Server.Storage.LoadAccess(token) if err != nil { fmt.Println("get token storage failure") flag = false } else { if storage.CreatedAt.Add(time.Duration(3600) * time.Second).Before(oauth.Server.Now()) { flag = false resp.SetError("invalid_grant test", "") } else { if clientId != storage.Client.GetId() { flag = false } else { openId := "" if queryUrl["open_id"] != nil { openId = queryUrl["open_id"][0] } if openId != "" { userData := storage.UserData.(map[string]interface{}) acId := int(userData["Ac_id"].(float64)) storageOpenId := GetOpenId(acId, clientId) if openId != storageOpenId { flag = false } } } } } if flag { resp.Output["code"] = 0 resp.Output["data"] = storage.Scope } else { resp.Output["code"] = 1 } // common.Write(w, ret) osin.OutputJSON(resp, w, r) }
// OAuth2 token endpoint func (o *Api) token(w http.ResponseWriter, r *http.Request) { log.Println(OAUTH2_API_PREFIX, "token: getting token") resp := o.oauthServer.NewResponse() defer resp.Close() if ar := o.oauthServer.HandleAccessRequest(resp, r); ar != nil { ar.Authorized = true o.oauthServer.FinishAccessRequest(resp, r, ar) } if resp.IsError && resp.InternalError != nil { log.Printf(OAUTH2_API_PREFIX+"token: error[%s] status[%d]", resp.InternalError.Error(), resp.StatusCode) } osin.OutputJSON(resp, w, r) }
func (s *Server) handleToken(w http.ResponseWriter, r *http.Request) { resp := s.server.NewResponse() defer resp.Close() if ar := s.server.HandleAccessRequest(resp, r); ar != nil { if err := s.access.HandleAccess(ar, w); err != nil { s.errorHandler.HandleError(err, w, r) return } s.server.FinishAccessRequest(resp, r, ar) } if resp.IsError && resp.InternalError != nil { util.HandleError(fmt.Errorf("internal error: %s", resp.InternalError)) } osin.OutputJSON(resp, w, r) }
// Authorize endpoint func Authorize(w http.ResponseWriter, r *http.Request) { server := OAuthComponent(r) resp := server.NewResponse() defer resp.Close() if ar := server.HandleAuthorizeRequest(resp, r); ar != nil { if !example.HandleLoginPage(ar, w, r) { return } ar.UserData = "test" // Get user_id ar.Authorized = true server.FinishAuthorizeRequest(resp, r, ar) } if resp.IsError && resp.InternalError != nil { logs.Error(resp.InternalError.Error()) } osin.OutputJSON(resp, w, r) }
func (o *OAuthHandler) AuthorizeClient(w http.ResponseWriter, r *http.Request) { server := o.server resp := server.NewResponse() defer resp.Close() if ar := server.HandleAuthorizeRequest(resp, r); ar != nil { if !o.handleLoginPage(ar, w, r) { return } ar.Authorized = true server.FinishAuthorizeRequest(resp, r, ar) } if resp.IsError || resp.InternalError != nil { //log.Printf("ERROR: %s\n", resp.InternalError) resp.StatusCode = http.StatusBadRequest } osin.OutputJSON(resp, w, r) }
func handleToken(w http.ResponseWriter, r *http.Request) { resp := server.NewResponse() defer resp.Close() if ar := server.HandleAccessRequest(resp, r); ar != nil { ar.Authorized = true server.FinishAccessRequest(resp, r, ar) // If an ID Token was encoded as the UserData, serialize and sign it. if idToken, ok := ar.UserData.(*IDToken); ok && idToken != nil { encodeIDToken(resp, idToken, jwtSigner) } } if resp.IsError && resp.InternalError != nil { fmt.Printf("ERROR: %s\n", resp.InternalError) } osin.OutputJSON(resp, w, r) }
func handleToken(w http.ResponseWriter, r *http.Request) { resp := server.NewResponse() defer resp.Close() if ar := server.HandleAccessRequest(resp, r); ar != nil { if u, p, ok := r.BasicAuth(); ok && u == ar.Client.GetId() && p == ar.Client.GetSecret() { ar.Authorized = true } server.FinishAccessRequest(resp, r, ar) } if resp.IsError { resp.StatusCode = 401 } osin.OutputJSON(resp, w, r) }