func (l *Grant) handleForm(user user.Info, w http.ResponseWriter, req *http.Request) { q := req.URL.Query() then := q.Get("then") clientID := q.Get("client_id") scopes := q.Get("scopes") redirectURI := q.Get("redirect_uri") client, err := l.clientregistry.GetClient(kapi.NewContext(), clientID) if err != nil || client == nil { l.failed("Could not find client for client_id", w, req) return } if err := scopeauthorizer.ValidateScopeRestrictions(client, scope.Split(scopes)...); err != nil { failure := fmt.Sprintf("%v requested illegal scopes (%v): %v", client.Name, scopes, err) l.failed(failure, w, req) return } uri, err := getBaseURL(req) if err != nil { glog.Errorf("Unable to generate base URL: %v", err) http.Error(w, "Unable to determine URL", http.StatusInternalServerError) return } csrf, err := l.csrf.Generate(w, req) if err != nil { glog.Errorf("Unable to generate CSRF token: %v", err) l.failed("Could not generate CSRF token", w, req) return } form := Form{ Action: uri.String(), Values: FormValues{ Then: then, ThenParam: thenParam, CSRF: csrf, CSRFParam: csrfParam, ClientID: client.Name, ClientIDParam: clientIDParam, UserName: user.GetName(), UserNameParam: userNameParam, Scopes: scopes, ScopesParam: scopesParam, RedirectURI: redirectURI, RedirectURIParam: redirectURIParam, ApproveParam: approveParam, DenyParam: denyParam, }, } l.render.Render(form, w, req) }
func (s *storage) convertToAuthorizeToken(data *osin.AuthorizeData) (*api.OAuthAuthorizeToken, error) { token := &api.OAuthAuthorizeToken{ ObjectMeta: kapi.ObjectMeta{ Name: data.Code, CreationTimestamp: unversioned.Time{Time: data.CreatedAt}, }, ClientName: data.Client.GetId(), ExpiresIn: int64(data.ExpiresIn), Scopes: scope.Split(data.Scope), RedirectURI: data.RedirectUri, State: data.State, } if err := s.user.ConvertToAuthorizeToken(data.UserData, token); err != nil { return nil, err } return token, nil }
func (c *ClientAuthorizationGrantChecker) HasAuthorizedClient(user user.Info, grant *api.Grant) (approved bool, err error) { id := c.registry.ClientAuthorizationName(user.GetName(), grant.Client.GetId()) authorization, err := c.registry.GetClientAuthorization(kapi.NewContext(), id) if errors.IsNotFound(err) { return false, nil } if err != nil { return false, err } if len(authorization.UserUID) != 0 && authorization.UserUID != user.GetUID() { return false, fmt.Errorf("user %s UID %s does not match stored client authorization value for UID %s", user.GetName(), user.GetUID(), authorization.UserUID) } // TODO: improve this to allow the scope implementation to determine overlap if !scope.Covers(authorization.Scopes, scope.Split(grant.Scope)) { return false, nil } return true, nil }
func (l *Grant) handleGrant(user user.Info, w http.ResponseWriter, req *http.Request) { if ok, err := l.csrf.Check(req, req.FormValue("csrf")); !ok || err != nil { glog.Errorf("Unable to check CSRF token: %v", err) l.failed("Invalid CSRF token", w, req) return } then := req.FormValue("then") scopes := req.FormValue("scopes") if len(req.FormValue(approveParam)) == 0 { // Redirect with rejection param url, err := url.Parse(then) if len(then) == 0 || err != nil { l.failed("Access denied, but no redirect URL was specified", w, req) return } q := url.Query() q.Set("error", "access_denied") url.RawQuery = q.Encode() http.Redirect(w, req, url.String(), http.StatusFound) return } clientID := req.FormValue("client_id") client, err := l.clientregistry.GetClient(kapi.NewContext(), clientID) if err != nil || client == nil { l.failed("Could not find client for client_id", w, req) return } clientAuthID := l.authregistry.ClientAuthorizationName(user.GetName(), client.Name) ctx := kapi.NewContext() clientAuth, err := l.authregistry.GetClientAuthorization(ctx, clientAuthID) if err == nil && clientAuth != nil { // Add new scopes and update clientAuth.Scopes = scope.Add(clientAuth.Scopes, scope.Split(scopes)) if _, err = l.authregistry.UpdateClientAuthorization(ctx, clientAuth); err != nil { glog.Errorf("Unable to update authorization: %v", err) l.failed("Could not update client authorization", w, req) return } } else { // Make sure client name, user name, grant scope, expiration, and redirect uri match clientAuth = &oapi.OAuthClientAuthorization{ UserName: user.GetName(), UserUID: user.GetUID(), ClientName: client.Name, Scopes: scope.Split(scopes), } clientAuth.Name = clientAuthID if _, err = l.authregistry.CreateClientAuthorization(ctx, clientAuth); err != nil { glog.Errorf("Unable to create authorization: %v", err) l.failed("Could not create client authorization", w, req) return } } if len(then) == 0 { l.failed("Approval granted, but no redirect URL was specified", w, req) return } http.Redirect(w, req, then, http.StatusFound) }
// HandleAuthorize implements osinserver.AuthorizeHandler to ensure the requested scopes have been authorized. // The AuthorizeRequest.Authorized field must already be set to true for the grant check to occur. // If the requested scopes are authorized, the AuthorizeRequest is unchanged. // If the requested scopes are not authorized, or an error occurs, AuthorizeRequest.Authorized is set to false. // If the response is written, true is returned. // If the response is not written, false is returned. func (h *GrantCheck) HandleAuthorize(ar *osin.AuthorizeRequest, resp *osin.Response, w http.ResponseWriter) (bool, error) { // Requests must already be authorized before we will check grants if !ar.Authorized { return false, nil } // Reset request to unauthorized until we verify the grant ar.Authorized = false user, ok := ar.UserData.(user.Info) if !ok || user == nil { utilruntime.HandleError(fmt.Errorf("the provided user data is not a user.Info object: %#v", user)) resp.SetError("server_error", "") return false, nil } client, ok := ar.Client.GetUserData().(*oauthapi.OAuthClient) if !ok || client == nil { utilruntime.HandleError(fmt.Errorf("the provided client is not an *api.OAuthClient object: %#v", client)) resp.SetError("server_error", "") return false, nil } // Normalize the scope request, and ensure all tokens contain a scope scopes := scope.Split(ar.Scope) if len(scopes) == 0 { scopes = append(scopes, scopeauthorizer.UserFull) } ar.Scope = scope.Join(scopes) // Validate the requested scopes if scopeErrors := validation.ValidateScopes(scopes, nil); len(scopeErrors) > 0 { resp.SetError("invalid_scope", scopeErrors.ToAggregate().Error()) return false, nil } invalidScopes := sets.NewString() for _, scope := range scopes { if err := scopeauthorizer.ValidateScopeRestrictions(client, scope); err != nil { invalidScopes.Insert(scope) } } if len(invalidScopes) > 0 { resp.SetError("access_denied", fmt.Sprintf("scope denied: %s", strings.Join(invalidScopes.List(), " "))) return false, nil } grant := &api.Grant{ Client: ar.Client, Scope: ar.Scope, Expiration: int64(ar.Expiration), RedirectURI: ar.RedirectUri, } // Check if the user has already authorized this grant authorized, err := h.check.HasAuthorizedClient(user, grant) if err != nil { utilruntime.HandleError(err) resp.SetError("server_error", "") return false, nil } if authorized { ar.Authorized = true return false, nil } // React to an unauthorized grant authorized, handled, err := h.handler.GrantNeeded(user, grant, w, ar.HttpRequest) if authorized { ar.Authorized = true } return handled, err }
func (l *Grant) handleGrant(user user.Info, w http.ResponseWriter, req *http.Request) { if ok, err := l.csrf.Check(req, req.FormValue(csrfParam)); !ok || err != nil { glog.Errorf("Unable to check CSRF token: %v", err) l.failed("Invalid CSRF token", w, req) return } req.ParseForm() then := req.FormValue(thenParam) scopes := scope.Join(req.Form[scopeParam]) username := req.FormValue(userNameParam) if username != user.GetName() { glog.Errorf("User (%v) did not match authenticated user (%v)", username, user.GetName()) l.failed("User did not match", w, req) return } if len(req.FormValue(approveParam)) == 0 || len(scopes) == 0 { // Redirect with an error param url, err := url.Parse(then) if len(then) == 0 || err != nil { l.failed("Access denied, but no redirect URL was specified", w, req) return } q := url.Query() q.Set("error", "access_denied") url.RawQuery = q.Encode() http.Redirect(w, req, url.String(), http.StatusFound) return } clientID := req.FormValue(clientIDParam) client, err := l.clientregistry.GetClient(kapi.NewContext(), clientID) if err != nil || client == nil { l.failed("Could not find client for client_id", w, req) return } if err := scopeauthorizer.ValidateScopeRestrictions(client, scope.Split(scopes)...); err != nil { failure := fmt.Sprintf("%v requested illegal scopes (%v): %v", client.Name, scopes, err) l.failed(failure, w, req) return } clientAuthID := l.authregistry.ClientAuthorizationName(user.GetName(), client.Name) ctx := kapi.NewContext() clientAuth, err := l.authregistry.GetClientAuthorization(ctx, clientAuthID) if err == nil && clientAuth != nil { // Add new scopes and update clientAuth.Scopes = scope.Add(clientAuth.Scopes, scope.Split(scopes)) if _, err = l.authregistry.UpdateClientAuthorization(ctx, clientAuth); err != nil { glog.Errorf("Unable to update authorization: %v", err) l.failed("Could not update client authorization", w, req) return } } else { // Make sure client name, user name, grant scope, expiration, and redirect uri match clientAuth = &oapi.OAuthClientAuthorization{ UserName: user.GetName(), UserUID: user.GetUID(), ClientName: client.Name, Scopes: scope.Split(scopes), } clientAuth.Name = clientAuthID if _, err = l.authregistry.CreateClientAuthorization(ctx, clientAuth); err != nil { glog.Errorf("Unable to create authorization: %v", err) l.failed("Could not create client authorization", w, req) return } } // Redirect, overriding the scope param on the redirect with the scopes that were actually granted url, err := url.Parse(then) if len(then) == 0 || err != nil { l.failed("Access granted, but no redirect URL was specified", w, req) return } q := url.Query() q.Set("scope", scopes) url.RawQuery = q.Encode() http.Redirect(w, req, url.String(), http.StatusFound) }
func (l *Grant) handleForm(user user.Info, w http.ResponseWriter, req *http.Request) { q := req.URL.Query() then := q.Get(thenParam) clientID := q.Get(clientIDParam) scopes := scope.Split(q.Get(scopeParam)) redirectURI := q.Get(redirectURIParam) client, err := l.clientregistry.GetClient(kapi.NewContext(), clientID) if err != nil || client == nil { l.failed("Could not find client for client_id", w, req) return } if err := scopeauthorizer.ValidateScopeRestrictions(client, scopes...); err != nil { failure := fmt.Sprintf("%v requested illegal scopes (%v): %v", client.Name, scopes, err) l.failed(failure, w, req) return } uri, err := getBaseURL(req) if err != nil { glog.Errorf("Unable to generate base URL: %v", err) http.Error(w, "Unable to determine URL", http.StatusInternalServerError) return } csrf, err := l.csrf.Generate(w, req) if err != nil { glog.Errorf("Unable to generate CSRF token: %v", err) l.failed("Could not generate CSRF token", w, req) return } grantedScopeNames := []string{} grantedScopes := []Scope{} requestedScopes := []Scope{} clientAuthID := l.authregistry.ClientAuthorizationName(user.GetName(), client.Name) if clientAuth, err := l.authregistry.GetClientAuthorization(kapi.NewContext(), clientAuthID); err == nil { grantedScopeNames = clientAuth.Scopes } for _, s := range scopes { requestedScopes = append(requestedScopes, getScopeData(s, grantedScopeNames)) } for _, s := range grantedScopeNames { grantedScopes = append(grantedScopes, getScopeData(s, grantedScopeNames)) } form := Form{ Action: uri.String(), GrantedScopes: grantedScopes, Names: GrantFormFields{ Then: thenParam, CSRF: csrfParam, ClientID: clientIDParam, UserName: userNameParam, Scopes: scopeParam, RedirectURI: redirectURIParam, Approve: approveParam, Deny: denyParam, }, Values: GrantFormFields{ Then: then, CSRF: csrf, ClientID: client.Name, UserName: user.GetName(), Scopes: requestedScopes, RedirectURI: redirectURI, }, } if saNamespace, saName, err := serviceaccount.SplitUsername(client.Name); err == nil { form.ServiceAccountName = saName form.ServiceAccountNamespace = saNamespace } l.render.Render(form, w, req) }