Beispiel #1
0
func (s *storage) convertFromAuthorizeToken(authorize *api.OAuthAuthorizeToken) (*osin.AuthorizeData, error) {
	user, err := s.user.ConvertFromAuthorizeToken(authorize)
	if err != nil {
		return nil, err
	}
	client, err := s.client.GetClient(kapi.NewContext(), authorize.ClientName)
	if err != nil {
		return nil, err
	}
	if err := scopeauthorizer.ValidateScopeRestrictions(client, authorize.Scopes...); err != nil {
		return nil, err
	}

	return &osin.AuthorizeData{
		Code:                authorize.Name,
		CodeChallenge:       authorize.CodeChallenge,
		CodeChallengeMethod: authorize.CodeChallengeMethod,
		Client:              &clientWrapper{authorize.ClientName, client},
		ExpiresIn:           int32(authorize.ExpiresIn),
		Scope:               scope.Join(authorize.Scopes),
		RedirectUri:         authorize.RedirectURI,
		State:               authorize.State,
		CreatedAt:           authorize.CreationTimestamp.Time,
		UserData:            user,
	}, nil
}
Beispiel #2
0
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)
}
Beispiel #3
0
// Validate validates a new client
func (s strategy) Validate(ctx kapi.Context, obj runtime.Object) field.ErrorList {
	auth := obj.(*api.OAuthClientAuthorization)
	validationErrors := validation.ValidateClientAuthorization(auth)

	client, err := s.clientGetter.GetClient(ctx, auth.ClientName)
	if err != nil {
		return append(validationErrors, field.InternalError(field.NewPath("clientName"), err))
	}
	if err := scopeauthorizer.ValidateScopeRestrictions(client, auth.Scopes...); err != nil {
		return append(validationErrors, field.InternalError(field.NewPath("clientName"), err))
	}

	return validationErrors
}
Beispiel #4
0
func (s *storage) convertFromAccessToken(access *api.OAuthAccessToken) (*osin.AccessData, error) {
	user, err := s.user.ConvertFromAccessToken(access)
	if err != nil {
		return nil, err
	}
	client, err := s.client.GetClient(kapi.NewContext(), access.ClientName)
	if err != nil {
		return nil, err
	}
	if err := scopeauthorizer.ValidateScopeRestrictions(client, access.Scopes...); err != nil {
		return nil, err
	}

	return &osin.AccessData{
		AccessToken:  access.Name,
		RefreshToken: access.RefreshToken,
		Client:       &clientWrapper{access.ClientName, client},
		ExpiresIn:    int32(access.ExpiresIn),
		Scope:        scope.Join(access.Scopes),
		RedirectUri:  access.RedirectURI,
		CreatedAt:    access.CreationTimestamp.Time,
		UserData:     user,
	}, nil
}
Beispiel #5
0
// 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
}
Beispiel #6
0
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)
}
Beispiel #7
0
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)
}